📄 u_div16.asm
字号:
;******************************************************************************
;* U_DIV16.ASM - 16 BIT STATE - v2.24 *
;* Copyright (c) 1996-2002 Texas Instruments Incorporated *
;******************************************************************************
;****************************************************************************
;* U$DIV/U$MOD - DIVIDE TWO UNSIGNED 32 BIT NUMBERS.
;*
;****************************************************************************
;*
;* 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
;*
;****************************************************************************
.state16
.align ; REQUIRED SO ADD PC IS WORD ALIGNED BELOW
.global U$DIV
.global U$MOD
dvs .set r2 ; WORK COPY OF THE DIVISOR (SHIFTED)
quo .set r3 ; WORK COPY OF THE QUOTIENT
tmp .set r4
U$DIV:
U$MOD: PUSH {r2-r4} ; SAVE CONTEXT
MOV dvs, r1 ; INITIALIZE THE DIVISOR (SHIFTED)
BEQ div_by_zero ; CHECK FOR DIVISION BY ZERO
LSR tmp, r0, #16 ; CALCULATE THE MAXIMUM DIVISOR
CMP dvs, tmp ; SHIFT AMOUNT WITH PSEUDO BINARY
BHI $1 ; SEARCH.
LSL dvs, dvs, #16 ;
$1: LSR tmp, r0, #8 ;
CMP dvs, tmp ;
BHI $2 ;
LSL dvs, dvs, #8 ;
$2: MOV quo, r0 ; NOW FIND EXACTLY WHERE THE SHIFTED
ADD tmp, pc, #108 ; DIVISOR SHOULD BE SO THAT WE CAN
cnt: LSR quo, quo, #1 ; JUMP INTO THE CORRECT LOCATION
SUB tmp, #12 ; OF THE UNROLLED DIVIDE LOOP.
CMP dvs, quo ;
BLS cnt ;
MOV quo, #0 ; INITIALIZE THE QUOTIENT
MOV pc, tmp ;
divl:
LSR dvs, dvs, #8 ; DIVIDE LOOP UNROLLED 8 TIMES
mod7: LSL tmp, dvs, #7 ;
CMP r0, tmp ; IF DIVIDEND IS LARGER THAN DIVISOR,
ADC quo, quo ; SHIFT A 1 INTO THE QUOTIENT, ELSE 0
CMP r0, tmp ; IF DIVIDEND IS LARGER THAN DIVISOR,
BCC mod6 ; SUBTRACT THE DIVISOR,
SUB r0, r0, tmp ;
mod6: LSL tmp, dvs, #6 ;
CMP r0, tmp ;
ADC quo, quo ;
CMP r0, tmp ;
BCC mod5 ;
SUB r0, r0, tmp ;
mod5: LSL tmp, dvs, #5 ;
CMP r0, tmp ;
ADC quo, quo ;
CMP r0, tmp ;
BCC mod4 ;
SUB r0, r0, tmp ;
mod4: LSL tmp, dvs, #4 ;
CMP r0, tmp ;
ADC quo, quo ;
CMP r0, tmp ;
BCC mod3 ;
SUB r0, r0, tmp ;
mod3: LSL tmp, dvs, #3 ;
CMP r0, tmp ;
ADC quo, quo ;
CMP r0, tmp ;
BCC mod2 ;
SUB r0, r0, tmp ;
mod2: LSL tmp, dvs, #2 ;
CMP r0, tmp ;
ADC quo, quo ;
CMP r0, tmp ;
BCC mod1 ;
SUB r0, r0, tmp ;
mod1: LSL tmp, dvs, #1 ;
CMP r0, tmp ;
ADC quo, quo ;
CMP r0, tmp ;
BCC mod0 ;
SUB r0, r0, tmp ;
mod0: CMP r0, dvs ;
ADC quo, quo ;
CMP r0, dvs ;
BCC $3 ;
SUB r0, r0, dvs ;
$3: CMP r1, dvs ; IF THERE IS SHIFTED DIVISOR, THEN
BCC divl ; CONTINUE THE LOOP.
MOV r1, quo ; ELSE DONE. PLACE THE QUOTIENT
POP {r2-r4} ; IT ITS RIGHT PLACE.
MOV pc, lr ;
div_by_zero:
MOV r0, #0 ; DIVIDE BY ZERO RETURNS ZERO
POP {r2-r4} ;
MOV pc, lr ;
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -