?? dividing.asm
字號:
;.global BCDDiv
.CSEG
main:
ldi r28, low(0x02FF -1)
ldi r29, high(0x02FF -1)
out 0x3e, r29
out 0x3d, r28 ;set stack pointer
ldi r30,low(BCDDivisor)
ldi r31,high(BCDDivisor)
ldi r28,low(BDCDivdend)
ldi r29,high(BDCDivdend)
ldi r26,low(BCDResult)
ldi r27,high(BCDResult)
rcall BCDDiv
/*function: two BCD digitall Div. [R27,R26]=[R29,R28]/[31,30] */
BCDDiv:
movw r24,r26
ldi r26,low(BCDDivdendBuffer)
ldi r27,high(BCDDivdendBuffer)
eor r23,r23 /*a ZERO needed*/
st X+,r23 /*set first byte of BCDDivdendBuffer as ZERO*/
ldi r21,(BCDigitalWidth+1)
skipZeroDividend:
dec r21
breq ZeroDividend
ld r22,Y+
cpi r22,0
breq skipZeroDividend
ldi r20,BCDigitalWidth
sub r20,r21
lsl r20
mov r23,r22
andi r23,0xf0
brne noSkipHighDividend
inc r20
rjmp SkipHighDividend
DividendcopyLoop:
mov r23,r22
andi r23,0xf0
noSkipHighDividend:
swap r23
st X+,r23
SkipHighDividend:
andi r22,0x0f
st X+,r22
dec r21
breq DividendCopyFinished
ld r22,Y+
rjmp DividendcopyLoop
ZeroDividend:
/*Dividend is zero. return zero here.*/
DividendCopyFinished:
ldi r21,(BCDDivdendBufferSize-BCDigitalWidth*2)
add r21,r20
eor r23,r23 /*a ZERO needed*/
FillDividendBufferWithZero:
dec r21
breq FillDividendFinished
st X+,r23 /*Set as ZERO*/
rjmp FillDividendBufferWithZero
FillDividendFinished:
LoadDivisor:
ldi r26,low(BCDDivisorBuffer)
ldi r27,high(BCDDivisorBuffer)
eor r23,r23 /*a ZERO needed*/
st X+,r23 /*set first byte of BCDDivdendBuffer as ZERO*/
ldi r21,(BCDigitalWidth+1)
skipZeroDivisor:
dec r21
breq ZeroDivisor
ld r22,Z+
cpi r22,0
breq skipZeroDivisor
ldi r28,BCDigitalWidth
sub r28,r21
lsl r28
mov r23,r22
andi r23,0xf0
brne noSkipHighDivisor
inc r28
rjmp SkipHighDivisor
DivisorcopyLoop:
mov r23,r22
andi r23,0xf0
noSkipHighDivisor:
swap r23
st X+,r23
SkipHighDivisor:
andi r22,0x0f
st X+,r22
dec r21
breq DivisorCopyFinished
ld r22,Z+
rjmp DivisorcopyLoop
ZeroDivisor:
/*Divisor is zero.....*/
DivisorCopyFinished:
ldi r21,(BCDDivisorBufferSize-BCDigitalWidth*2)
add r21,r28
eor r23,r23 /*a ZERO needed*/
FillDivisorBufferWithZero:
dec r21
breq FillDivisorFinished
st X+,r23 /*Set as ZERO*/
rjmp FillDivisorBufferWithZero
FillDivisorFinished:
ldi r21,(BCDDivisorBufferSize-1)
DivisorNotTailZeroCountLoop:
ld r23,-X
cpi r23,0
brne f1
dec r21
brne DivisorNotTailZeroCountLoop
/*r21: length of Divisor, without 0 in tail*/
/*r20: Shift of Dividend*/
/*r28: Shift of Diivisor*/
/*an absolute shift is gotten by r20-r28*/
f1:
sub r20,r28
/*we release r28 here,by reserve the absolute shift only*/
/*Do DIV:*/
movw r26,r24
eor r24,r24 /* r24:Result Index, 0 ~ (BCDigitalWidth)*2 */
eor r22,r22 /*a ZERO needed*/
ldi r30,low(BCDDivisorBuffer)
ldi r31,high(BCDDivisorBuffer) /* Z=&BCDDivisorBuffer */
ldi r28,low(BCDDivdendBuffer)
ldi r29,high(BCDDivdendBuffer)
inc r21
TwoDigitalProcess:
eor r19,r19
NumberSubLoop:
add r30,r21
adc r31,r22 /* Z = &BCDDivisorBuffer + r21 */
add r28,r21
adc r29,r22
mov r18,r21
clc
DigitalSubLoop:
ld r25,-Z
ld r23,-Y
sbc r23,r25
brcc noBorrow
ldi r25,10
add r23,r25
sec
noBorrow:
st Y,r23
dec r18
brne DigitalSubLoop
inc r19
brcc NumberSubLoop
adiw r28,1
inc r24
/*Prepare environment for adding*/
eor r17,r17
NumberAddLoop:
mov r18,r21
add r30,r21
adc r31,r22 /*a ZERO */ /* Z = &BCDDivisorBuffer + r21 */
add r28,r21
adc r29,r22 /*a ZERO*/
clc
DigitalAddLoop:
ld r25,-Z
ld r23,-Y
adc r23,r25
cpi r23,10
brlo noCarry
ldi r25,10
sub r23,r25
sec
rjmp saveResult
noCarry:
clc /*Carry Flag has been changed by cpi instruction*/
saveResult:
st Y,r23
dec r18
brne DigitalAddLoop
inc r17
brcc NumberAddLoop
adiw r28,1
dec r19
ldi r25,10
sub r25,r17
swap r19
add r19,r25
st X+,r19
inc r24
cpi r24,((BCDigitalWidth)*2)
brne TwoDigitalProcess
ret
;; .data
.DSEG
nothing: .byte 0x100
.set BCDigitalWidth = 5
.set BCDDivdendBufferSize=((BCDigitalWidth)*4+1)
.set BCDDivisorBufferSize=((BCDigitalWidth)*2+1)
BCDDivdendBuffer: .byte BCDDivdendBufferSize
BCDDivisorBuffer: .byte BCDDivisorBufferSize
BDCDivdend: .db 0x98,0x76,0x54,0x32,0x10
BCDDivisor: .db 0x12,0x23,0x56,0x00,0x00
BCDResult: .byte BCDigitalWidth
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -