?? 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)
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+1)
add r21,r20
eor r23,r23
FillDividendBufferWithZero:
dec r21
breq FillDividendFinished
st X+,r23
rjmp FillDividendBufferWithZero
FillDividendFinished:
LoadDivisor:
ldi r26,low(BCDDivisorBuffer)
ldi r27,high(BCDDivisorBuffer)
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+1)
add r21,r28
eor r23,r23
FillDivisorBufferWithZero:
dec r21
breq FillDivisorFinished
st X+,r23
rjmp FillDivisorBufferWithZero
FillDivisorFinished:
ldi r21,BCDDivisorBufferSize
DivisorNotTailZeroCountLoop:
ld r23,-X
cpi r23,0
brne f1
dec r21
brne DivisorNotTailZeroCountLoop
/*r21: length of Dividor, without 0 in tail*/
/*r20: Shift of Dividend*/
/*r28: Shift of Diividor*/
/*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
/* r24:Result Index, 0 ~ (BCDigitalWidth)*2 */
eor r24,r24
eor r22,r22
ldi r30,low(BCDDivisorBuffer)
ldi r31,high(BCDDivisorBuffer) /* Z=&BCDDivisorBuffer */
ldi r28,low(BCDDivdendBuffer)
ldi r29,high(BCDDivdendBuffer)
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
sbiw r30,1
eor r17,r17
/*Prepare environment for adding*/
NumberAddLoop:
mov r18,r21
inc r18
add r30,r18
adc r31,r22 /* Z = &BCDDivisorBuffer + r21 */
add r28,r18
adc r29,r22
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,2
adiw r30,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)
.set BCDDivisorBufferSize=((BCDigitalWidth)*2)
.set BCDDividResultBufferSize=((BCDigitalWidth)*2)
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 + -