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

📄 dividing.asm

📁 浮点除法子程序,可以高效率计算浮点浮点除法,程序短小精干,非常讨巧
💻 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 + -