找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2187|回复: 0
收起左侧

AVR 系列单片机汇编 数值运算子程序

[复制链接]
ID:901054 发表于 2021-4-5 22:31 | 显示全部楼层 |阅读模式
;***************************************************************************
;*
;* "mpy16u" - 16x16 Bit Unsigned Multiplication
;*
;* This subroutine multiplies the two 16-bit register variables
;* mp16uH:mp16uL and mc16uH:mc16uL.
;* The result is placed in m16u3:m16u2:m16u1:m16u0.
;*
;* Number of words        :14 + return
;* Number of cycles        :153 + return
;* Low registers used        :None
;* High registers used  :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2,
;*                          m16u3,mcnt16u)
;*
;***************************************************************************

;***** Subroutine Register Variables

.def        mc16uL        =r16                ;multiplicand low byte
.def        mc16uH        =r17                ;multiplicand high byte
.def        mp16uL        =r18                ;multiplier low byte
.def        mp16uH        =r19                ;multiplier high byte
.def        m16u0        =r18                ;result byte 0 (LSB)
.def        m16u1        =r19                ;result byte 1
.def        m16u2        =r20                ;result byte 2
.def        m16u3        =r21                ;result byte 3 (MSB)
.def        mcnt16u        =r22                ;loop counter

;***** Code

mpy16u:        clr        m16u3                ;clear 2 highest bytes of result
        clr        m16u2
        ldi        mcnt16u,16        ;init loop counter
        lsr        mp16uH
        ror        mp16uL

m16u_1:        brcc        noad8                ;if bit 0 of multiplier set
        add        m16u2,mc16uL        ;add multiplicand Low to byte 2 of res
        adc        m16u3,mc16uH        ;add multiplicand high to byte 3 of res
noad8:        ror        m16u3                ;shift right result byte 3
        ror        m16u2                ;rotate right result byte 2
        ror        m16u1                ;rotate result byte 1 and multiplier High
        ror        m16u0                ;rotate result byte 0 and multiplier Low
        dec        mcnt16u                ;decrement loop counter
        brne        m16u_1                ;if not done, loop more
        ret




;......................

;被除数:R19(HIGH)R18 R17 R16(LOW)

;除数:R21(HIGH)R20

;结果:R17(HIGH)R16
;余数:R19(HIGH)R18
;计数器,R22

;...................................................
d32v16u:                   ; 32位/16位无符号除法
        cp r18,r20         ;被除数高16位 > 除数
        cpc r19,r21        ;结果溢出
        brcc        cc            
        ldi r22,$10        ;初始化循环计数器
        rol r16            ;左移被除数
        rol r17
aa:
        rol r18            ;左移余数(被除数移到除数)
        bst r19,7
        rol r19
        sub r18,r20        ;余数-除数
        sbc r19,r21
        brts         loop       ;够减,跳至 loop
        brcc         loop
        add r18,r20        ;不够减,再加除数
        adc r19,r21
        clc                ;清进位位
        rjmp         loop1
loop:
        sec                ;置进位位
loop1:
        rol r16            ;左移结果
        rol r17
        dec r22            ;计数器减 1
        brne        aa         ;不为 0,再循环
        clt                ;清 t 标志
        ret
cc:
        set                ;置 t 标志
        ret

;...................................











;......................

;被除数:R17(HIGH) R16(LOW)

;除数:R21(HIGH)R20

;结果:R17(HIGH)R16
;余数:R19(HIGH)R18
;计数器,R22

;...................................................
d16v16u:                   ; 32位/16位无符号除法
;        cp r18,r20         ;被除数高16位 > 除数
;        cpc r19,r21        ;结果溢出
;        brcc        cc            
       
        clr r19
        clr r18
       
        ldi r22,$10        ;初始化循环计数器
        rol r16            ;左移被除数
        rol r17
vaa:
        rol r18            ;左移余数(被除数移到除数)
        bst r19,7
        rol r19
        sub r18,r20        ;余数-除数
        sbc r19,r21
        brts         vloop       ;够减,跳至 loop
        brcc         vloop
        add r18,r20        ;不够减,再加除数
        adc r19,r21
        clc                ;清进位位
        rjmp         vloop1
vloop:
        sec                ;置进位位
vloop1:
        rol r16            ;左移结果
        rol r17
        dec r22            ;计数器减 1
        brne        vaa         ;不为 0,再循环
        clt                ;清 t 标志
        ret
;cc:
;       set                ;置 t 标志
;        ret


;..............................










;...r17:r16(hex)--->r20(万位):r19(千位):r18(百位):r17(十位):r16(bcd)
                   ; 结果值在每字节里只存一位,即在每字节的低半字节里      
;.....................;调用16位二进制转5位十进制子程
b16td5:
        ser r20              ;r20先送-1
b16td5_1:  
        inc r20              ;r20增1
    subi r16,low(10000)  ;(r17:r16)-10000
        sbci r17,high(10000)
        brcc         b16td5_1     ;够减则返回b16td5_1
        subi r16,low(-10000) ;不够减+10000,恢复余数
        sbci r17,high(-10000)
        ser r19              ;r19先送-1
b16td5_2:
        inc r19              ;r19增1   
        subi r16,low(1000)   ;(r17:r16)-1000
        sbci r17,high(1000)            
        brcc         b16td5_2     ;够减则返回b16td5_2
        subi r16,low(-1000)  ;不够减+1000,恢复余数
        sbci r17,high(-1000)
        ser r18              ;r18先送-1
b16td5_3:
        inc r18              ;r18增1   
subi r16,low(100)            ;(r17:r16)-100
        sbci r17,high(100)            
        brcc         b16td5_3     ;够减则返回b16td5_3
        subi r16,low(-100)   ;不够减+100,恢复余数
        sbci r17,high(-100)
        ser r17              ;r17先送-1
b16td5_4:
        inc r17              ;r17增1
        subi r16,10          ;(r17:r16)-10         
        brcc         b16td5_4     ;够减则返回b16td5_4               
        subi r16,-10         ;不够减+10,恢复余数
    ret
;...........................................







;...............;r16(high)r19(low)/r17 =r16(结果)+r19(余数)

d16v8u:                 ;16/8无符号除法
        cp r16,r17      ;被除数高字节 > 除数   
        brcc   ddd      ;结果溢出
        ldi r18,8       ;初始化循环计数器
        rol r19         ;左移余数(被除数低字节)
aaa:
        bst r16,7
        rol r16         ;左移被除数高字节
        sub r16,r17     ;r16减r17
        brts        bbb
        brcc        bbb
        add r16,r17     ;结果为负,则r16加r17
        clc             ;清进位位
        rjmp        ccc
bbb:
        sec             ;够减,置进位位
ccc:
        rol r19         ;左移余数
        dec r18         ;减计数器
        brne        aaa     ;没完成再循环
        clc
        mov r17,r16        
        mov r16,r19     ;r16存放结果
        mov r19,r17     ;r19存放余数
        ret
ddd:
        set
        ret

;..................................

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表