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

📄 asm.asm

📁 与AVR开发相关的一百个实例,源码用ASM语言编写
💻 ASM
📖 第 1 页 / 共 5 页
字号:
定点运算和定点数制转换   
        ;范例1
LSDAA:  ADC     R16,R16      ;十进制数(在R16中)左移调整子程序
ADDAA:  IN      R6,SREG      ;bcd码相加调整子程序,先保存相加后的
        LDI     R17,$66      ;状态the old status
        ADD     R16,R17      ;再将和预加立即数$66
        IN      R17,SREG     ;输入相加后新状态(the new status)
        OR      R6,R17       ;新旧状态相或
        SBRS    R6,0         ;相或后进位置位则跳行
        SUBI    R16,$60      ;否则减去$60(十位bcd不满足调整条件)
        SBRS    R6,5         ;半进位置位则跳行
        SUBI    R16,6        ;否则减去$06(个位bcd不满足调整条件)
        ROR     R6           ;向高位字节BCD返还进位位!
        RET
       ;范例2
       
SUDAA:  BRCC    SBD1         ;bcd码减法调整子程序,差在R16中
        BRHC    SBD3         
        SUBI    R16,$66      ;进位半进位都置位,将差减去立即数$66
        SEC                  ;并恢复借位C
        RET                  ;ret. with seC
SBD1:   BRHC    SBD2         ;进位半进位都清位,返回
        SUBI    R16,6        ;进位清除而半进位置位,将差减去6
SBD2:   RET                  ;ret. with clC
SBD3:   SUBI    R16,$60      ;进位置位而半进位清除,将差减去$60
        SEC                  ;并恢复借位C
        RET                  ;ret. with seC

       ;范例3
RSDAA:  SBRC    R16,7        ;bcd码(在R16中)右移调整子程序
        SUBI    R16,$30      ;十位BCD最高位为1(代表8),将其变为5(否则跳行)
        SBRC    R16,3         
        SUBI    R16,3        ;个位BCD最高位为1(代表8),将其变为5(否则跳行)
        RET
        
       ;范例4
ADBCD4: MOV     R16,R15      ;4字节压缩bcd码相加子程序
        ADD     R16,R11      ;R12,R13,R14,R15内为被加数,R8,R9,R10,R11内为加数
        RCALL   ADDAA        ;相加后调整
        MOV     R15,R16      ;并返还调整后结果
        MOV     R16,R14
        ADC     R16,R10
        RCALL   ADDAA
        MOV     R14,R16
        MOV     R16,R13
        ADC     R16,R9
        RCALL   ADDAA
        MOV     R13,R16
        MOV     R16,R12
        ADC     R16,R8        
        RCALL   ADDAA
        MOV     R12,R16
        RET
        
       ;范例5
ADBCD:  LDI     R16,4        ;多字节压缩bcd码相加子程序
        MOV     R7,R16       ;(r7):字节数
        CLC
ADLOP:  LD      R16,-X       ;X-1指向被加数;  
        LD      R6,-Y        ;Y-1指向加数
        ADC     R16,R6
        RCALL   ADDAA        ;相加后调整
        ST      X,R16        ;返还调整后结果
        DEC     R7          
        BRNE    ADLOP
        RET
        
       ;范例6
SUBCD4: MOV     R16,R15       ;4字节压缩bcd码减法子程序
        SUB     R16,R11       ;R12,R13,R14,R15内为被减数,R8,R9,R10,R11内为减数
        RCALL   SUDAA         ;相减后调整
        MOV     R15,R16       ;并返还调整后结果
        MOV     R16,R14
        SBC     R16,R10
        RCALL   SUDAA
        MOV     R14,r16
        MOV     R16,R13
        SBC     R16,R9
        RCALL   SUDAA
        MOV     R13,R16
        MOV     R16,R12
        SBC     R16,R8
        RCALL   SUDAA
        MOV     R12,R16
        RET
        
       ;范例7
SUBCD:  LDI     R16,4        ;多字节压缩bcd码相减子程序
        MOV     R7,R16       ;(r7):压缩bcd码字节数
        CLC
SUBLP:  LD      R16,-X       ;X-1指向被减数
        LD      R6,-Y        ;Y-1指向减数
        SBC     R16,R6
        RCALL   SUDAA        ;相减后调整
        ST      X,R16        ;返还调整后结果
        DEC     R7
        BRNE    SUBLP
        RET
       ;范例8                ;16位被乘数*16位乘数-->32位积
MUL16:  LDI     R16,17       ;(r10r11)*(r14r15)-->r12r13r14r15
        ClR     R12
        ClR     R13          ;积的高位字预清除
        CLC                  ;第1次只右移,不相加
MLOOP:  BRCC    MUL1         ;
        ADD     R13,R11      ;乘数右移移出位为1,将被乘数加入部分积
        ADC     R12,R10
MUL1:   ROR     R12
        ROR     R13
        ROR     R14
        ROR     R15          ;部分积连同乘数整体右移1位
        DEC     R16
        BRNE    MLOOP        ;17次右移后结束 
        RET
        
       ;范例9                ;16位整数被乘数*16位小数乘数-->16位整数积,精确到0.5
MUL165: RCALL   MUL16        ;先得到32位积
        SBRS    R14,7        ;积小数部分最高位为1,将整数部分加1
        RET                  ;否则返回
        LDI     R17,255
        SUB     R13,R17
        SBC     R12,R17      ;以减去-1($FFFF)替代加1
        RET
        
       ;范例10               ;32位被除数/16位除数-->16位商,精确到1
DIV16:  LDI     R16,16       ;(r12r13r14r15)/(r10r11)-->r14r15
DLOOP:  LSL     R15          
        ROL     R14
        ROL     R13
        ROL     R12          ;被除数左移1位
        BRCS    DI1
        SUB     R13,R11
        SBC     R12,R10      ;移出位为0,被除数高位字减去除数试商
        BRCC    DI2          ;够减,本位商为1
        ADD     R13,R11
        ADC     R12,R10      ;否则恢复被除数
        RJMP    DI3          ;本位商0
DI1:    SUB     R13,R11
        SBC     R12,R10      ;移出位为1,被除数高位字减去除数
DI2:    INC     R15          ;本位商1
DI3:    DEC     R16
        BRNE    DLOOP
        RET
        
       ;范例11               ;32位被除数/16位除数-->16位商,精确到0.5 
                             ;可能产生溢出!例$7FFFC000/$8000=$FFFF.8->$10000!
DIV165: RCALL   DIV16        ;(r12r13r14r15)/(r10r11)-->r14r15
        LSL     R13          
        ROL     R12          ;余数乘2
        BRCS    D165         ;有进位,转5入
        SUB     R13,R11
        SBC     R12,R10      ;否则,余数乘2减去除数
        BRCS    D164         ;不够减,转4舍
D165:   CLR     R13          ;否则将商增1
        SEC                  
        ADC     R15,R13
        ADC     R14,R13
        ADC     R13,R13      ;若有溢出,溢出位在R13中
        RET
D164:   CLR     R13
        RET
       ;范例12               ;32位整数/16位整数->16整数+16位小数->4字节浮点数
                             ;(r12r13r14r15)/(r10r11)-->r12r13r14r15
DIV16F: RCALL   DIV16        ;先做整数除法
        MOV     R9,r15       
        MOV     R8,r14       ;保存整数部分
        CLR     R15
        CLR     R14
        RCALL   DIV16        ;除得小数部分
        MOV     R11,R15
        MOV     R15,R14
        MOV     R13,R8
        MOV     R14,R9       ;整数部分在r13r14,小数部分在r15r11
        LDI     R17,$90      ;预设阶码$90(整数为16位)
        MOV     R12,R17
        LDI     R17,32       ;设32次右移
DIV16L: SBRC    R13,7      
        RJMP    NMLDN        ;最高位为1,已完成规格化
        LSL     R11          ;否则继续右移R13,R14,R15,R11
        ROL     R15
        ROL     R14
        ROL     R13          
        DEC     R12          ;阶码减1
        DEC     R17
        BRNE    DIV16L       
        CLR     R12          ;右移达32次,浮点数为零,置零阶
        RET
NMLDN:  SBRS    R11,7        
        RJMP    DIVRT        ;欲舍去部分(R11)最高位为0,转4舍 
        RCALL   INC3         ;否则尾数部分增1
        BRNE    DIVRT
        INC     R12          ;尾数增1后变为0,改为0.5,并将阶码增1
DIVRT:  LDI     R17,$7F      ;将尾数最高位清除,表示正数(负数不要清除)
        AND     R13,R17      ;规格化浮点数在R12(阶码)R13R14R15(尾数)中
        RET
        
       ;范例13               ;(R16,R12,R13,R14,R15)/(R10,R11)-->R13,R14,R15
DIV24:  CLR     R16          ;32位整数/16位整数->24位整数,要求(R10)不为0;否则
                                                   ;要求(R12)<(R11)
DIV40:  LDI     17,24        ;40位整数/16位整数->24位整数 要求(R16,R12)
LXP:    LSL     R15          ; <(R10,R11)
        ROL     R14
        ROL     R13
        ROL     R12
        ROL     R16
        BRCC    LXP1
        SUB     R12,R11      ;右移后C=1 够减
        SBC     R16,R10      ;被除数减去除数
        RJMP    DIV0         ;本位商为1
LXP1:   SUB     R12,R11      ;C=0
        SBC     R16,R10      ;被除数减去除数试商
        BRCC    DIV0         ;C=0 够减,本位商1
        ADD     R12,R11
        ADC     R16,R10      ;否则恢复被除数,本位商0
        RJMP    DIV1
DIV0:   INC     R15          ;记本位商1
DIV1:   DEC     R17
        BRNE    LXP
        LSL     R12
        ROL     R16
        BRCS    GINC         ;C=1,5入
        SUB     R12,R11
        SBC     R16,R10
        BRCS    RET3         ;不够减,舍掉
GINC:   RCALL   INC3         ;将商增1
RET3:   RET

       ;范例14               ;定点整数(最大$FFFFFFFF)开平方子程序
INTSQR: LDI     R16,17       ;SQR(R12,R13,R14,R15)-->(r15r8r9)
        CLR     R8           ;R8,R9存储平方根
        CLR     R9           ;r10,r11,r12,r13,r14,r15
        CLR     R10          ; r8, r9(根)          r16 (counter)
        CLR     R11          ;r10,r11:被开平方数扩展字节
        LDI     R17,$40      
SQR0:   SUB     R12,R17
        SBC     R11,R9
        SBC     R10,R8
        BRCS    SQR1
        SEC                  ;试根够减,本位根1
        RJMP    SQR2
SQR1:   ADD     R12,R17
        ADC     R11,R9
        ADC     R10,R8
        CLC                  ;否则恢复被开平方数,本位根0
SQR2:   DEC     R16
        BRNE    SQR3         ;when the No.17bit of root be getting
SQR20: ADC     R9,R15       ;R15 HAVE BEEN CLEARED!
        ADC     R8,R15
        ADC     R15,R15      ;将开出之根4舍5入,使根最大可达65536(=$10000)!
        RET                  ;for example:sqr.($ffff0001)≈$10000
SQR3:   ROL     R9
        ROL     R8           ;记本位根
        LSL     R15
        ROL     R14
        ROL     R13
        ROL     R12          
        ROL     R11
        ROL     R10          ;被开平方数连同其扩展字节左移一位
        LSL     R15
        ROL     R14
        ROL     R13
        ROL     R12
        ROL     R11
        ROL     R10          ;被开平方数连同其扩展字节再次左移一位/左移2位开出1位根
        BRCS    SQR20        ;被开平方数左移2位后,若进位置位,则仅表明第17位根
                                                   ;已被提前开出且该位根=1,将平方根增1,开平方结束。
        RJMP    SQR0         ;否则转试下一位根	
        
       ;范例15               ;定点整数二翻十
CONV1:  LDI     R17,24       ;r12r13r14r15<--(r9r10r11)左移24次
        MOV     R7,R17       ;例:16777215<--$FFFFFF
        CLR     R12
        CLR     R13          ;68719476735<--$FFFFFFFFF
        CLR     R14          ;1099511627775<--$FFFFFFFFFF
        CLR     R15          ;十进制数存储区予清除
CV1:    LSL     R11
        ROL     R10
        ROL     R9           ;二进制数整体左移一位
        MOV     R16,R15
        RCALL   LSDAA
        MOV     R15,R16
        MOV     R16,R14
        RCALL   LSDAA
        MOV     R14,R16
        MOV     R16,R13
        RCALL   LSDAA
        MOV     R13,R16      
        MOV     R16,R12
        RCALL   LSDAA         ;十进制数左移并调整
        MOV     R12,R16
        DEC     R7
        BRNE    CV1
        RET
        
       ;范例16               ;定点整数十翻二
CONV2:  LDI     R17,24       ;(r9r10r11)-->r13r14r15,右移24次
        CLR     R31          ;例:999999-->$0F423F
        MOV     R7,R17       ; 99999999-->$05F5E0FF
CV2:    LSR     R9
        ROR     R10
        ROR     R11          
        ROR     R13
        ROR     R14
        ROR     R15           ;十进制数连同二进制数右移一位
        LDI     R30,12        ;数据指针
CV2L:   LD      R16,-Z
        RCALL   RSDAA         ;十进制数右移调整
        ST      Z,R16
        CPI     R30,9         ;十进制数各字节调整完毕?
        BRNE    CV2L
        DEC     R7            ;右移次数(24次)完成?
        BRNE    CV2
        RET
        
       ;范例17               ;定点小数二翻十
CONV3:  LDI     R17,24       ;(r13r14r15)--->r9r10r11r12右移24次
CONV31: MOV     R7,R17
        CLR     R9           
        CLR     R10          ;例:$0.FFFFFF-->0.99999994
        CLR     R11          ;$0.FFFFFFFF-->0.999999999767
        CLR     R12          ;$0.FFFFFFFFF->0.999999999985448
        CLR     R31
CV3:    LSR     R13
        ROR     R14
        ROR     R15
        ROR     R9
        ROR     R10
        ROR     R11
        ROR     R12          ;二进制数连同十进制数右移一位
        LDI     R30,9
CV3L:   LD      R16,Z
        RCALL   RSDAA        ;十进制数右移调整
        ST      Z+,r16
        CPI     R30,13
        BRNE    CV3L         ;十进制数各字节调整完毕?
        DEC     R7
        BRNE    CV3          ;右移次数(24次)完成?
        RET
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -