⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i_div32.asm

📁 MMI层OBJ不能完全编译
💻 ASM
字号:
;******************************************************************************
;* I_DIV32.ASM  - 32 BIT STATE -  v2.54                                       *
;* Copyright (c) 1996-2004 Texas Instruments Incorporated                     *
;******************************************************************************

;****************************************************************************
;* I_DIV/I_MOD - DIVIDE TWO SIGNED 32 BIT NUMBERS.
;* I$DIV/I$MOD - 16 BIT STATE INTERFACE TO I_DIV/I_MOD.
;*  
;****************************************************************************
;*
;*   o DIVIDEND IS IN r0
;*   o DIVISOR IS IN r1
;*
;*   o QUOTIENT IS PLACED IN r1
;*   o REMAINDER IS PLACED IN r0
;*
;*   o DIVIDE BY ZERO RETURNS ZERO
;*   o SIGN OF REMAINDER IS THE SIGN OF THE DIVIDEND
;*
;****************************************************************************
	.global I_DIV
	.global I_MOD

dvs	.set	r2		; WORK COPY OF THE DIVISOR (SHIFTED)
quo	.set	r3		; WORK COPY OF THE QUOTIENT
negs	.set	lr		; SAVED COPY OF THE SIGNS

	.if !$$isdefed("__small_divide__")
	.global I$DIV
	.global I$MOD

	.align
	.state16
I$DIV:	.asmfunc 
I$MOD:	BX	pc			; CHANGE TO 32-BIT STATE
	NOP
	.endasmfunc
	.endif
	
	.state32
I_DIV:	.asmfunc stack_usage(12)
I_MOD:	STMFD	sp!, {dvs, quo, lr}	; SAVE CONTEXT
	
	MOV	negs, r1, LSR #1	; MOVE THE SIGN OF THE DIVISOR TO negs
	EORS	negs, negs, r0, ASR #1	; MOVE THE SIGN OF THE DIVIDEND TO negs
	RSBMI	r0, r0, #0		; ABSOLUTE SIGN OF THE DIVIDEND

	ANDS	quo, r1, #0x80000000	; INITIALIZE THE QUOTIENT
	RSBNE	r1, r1, #0		; ABSOLUTE SIGN OF THE DIVISOR
	MOVS	dvs, r1			; CHECK FOR DIVISION BY ZERO, AND
	BEQ	div_by_zero		; INITIALIZE THE DIVISOR (SHIFTED)

	CMP	dvs, r0,  LSR #16	; CALCULATE THE MAXIMUM DIVISOR
	MOVLS	dvs, dvs, LSL #16	; SHIFT AMOUNT WITH PSEUDO BINARY
	CMP	dvs, r0,  LSR #8	; SEARCH.
	MOVLS	dvs, dvs, LSL #8	;

	CMP	dvs, r0, LSR #1		; NOW FIND EXACTLY WHERE THE SHIFTED
	BHI	mod1			; DIVISOR SHOULD BE SO THAT WE CAN
	CMP	dvs, r0, LSR #2		; JUMP INTO THE CORRECT LOCATION
	BHI	mod2			; OF THE UNROLLED DIVIDE LOOP.
	CMP	dvs, r0, LSR #3		;
	BHI	mod3			;
	CMP	dvs, r0, LSR #4		;
	BHI	mod4			;
	CMP	dvs, r0, LSR #5		;
	BHI	mod5			;
	CMP	dvs, r0, LSR #6		;
	BHI	mod6			;
	CMP	dvs, r0, LSR #7		;
	BHI	mod7			;

divl:					; DIVIDE LOOP UNROLLED 8 TIMES
	CMP	r0, dvs, LSL #7		; IF DIVIDEND IS LARGER THAN DIVISOR,
	ADC	quo, quo, quo		; SHIFT A 1 INTO THE QUOTIENT AND 
	SUBCS	r0, r0, dvs, LSL #7	; SUBTRACT THE DIVISOR, ELSE SHIFT A 0.
	CMP	r0, dvs, LSL #6		;

mod7:	ADC	quo, quo, quo		;
	SUBCS	r0, r0, dvs, LSL #6	;
	CMP	r0, dvs, LSL #5		;

mod6:	ADC	quo, quo, quo		;
	SUBCS	r0, r0, dvs, LSL #5	;
	CMP	r0, dvs, LSL #4		;

mod5:	ADC	quo, quo, quo		;
	SUBCS	r0, r0, dvs, LSL #4	;
	CMP	r0, dvs, LSL #3		;

mod4:	ADC	quo, quo, quo		;
	SUBCS	r0, r0, dvs, LSL #3	;
	CMP	r0, dvs, LSL #2		;

mod3:	ADC	quo, quo, quo		;
	SUBCS	r0, r0, dvs, LSL #2	;
	CMP	r0, dvs, LSL #1		;

mod2:	ADC	quo, quo, quo		;
	SUBCS	r0, r0, dvs, LSL #1	;

mod1:	CMP	r0, dvs			;
	ADC	quo, quo, quo		;
	SUBCS	r0, r0, dvs		;

	CMP	r1, dvs			; IF THERE IS SHIFTED DIVISOR, THEN
	MOVCC	dvs, dvs, LSR #8	; CONTINUE THE LOOP.
	BCC	divl			;

	MOV	r1, quo			; ELSE DONE. PLACE THE QUOTIENT
	MOVS	negs, negs, LSL #1	; IT ITS RIGHT PLACE, AND
	RSBMI	r1, quo, #0		; SET THE SIGN OF THE QUOTIENT AND
	RSBCS	r0, r0, #0		; REMAINDER.
	.if !$$isdefed("__small_divide__")
	LDMFD	sp!, {dvs, quo, lr}
	BX	lr
	.else
	LDMFD	sp!, {dvs, pc}
	.endif

div_by_zero:
	MOV	r0, #0			; DIVIDE BY ZERO RETURNS ZERO
	.if !$$isdefed("__small_divide__")
	LDMFD	sp!, {dvs, quo, lr}
	BX	lr
	.else
	LDMFD	sp!, {dvs, pc}
	.endif

	.endasmfunc

	.end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -