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

📄 16位乘除法.asm

📁 PIC16位乘除法
💻 ASM
📖 第 1 页 / 共 5 页
字号:
CHEK_A    BTFSC     ACCAHI,7    ;ACCA为负?
    CALL     NEG_A    ;ACCA为负,取补(NEG_A子程序请参见
            ;16×16位定点数乘法子程序NEG_A)
    RETURN        ;ACCA和ACCB均为负,返回
【校验举例1】 -23775÷(-240)=99.0625(十进制)
化为十六进制数:A321H÷FF10H;
结果:(商)0063H,(余数)000FH(十六进制)。
【校验举例2】 769÷3856=0.199429(十进制)
化为十六进制数:0301H÷0F10H;
结果:(商)0000H,(余数)0301H(十六进制)。
【例程】
MAIN    MOVLW    0X01    ;被除数0301H送ACCB
    MOVWF    ACCBLO
    MOVLW    0X03
    MOVWF    ACCBHI
    MOVLW    0X10    ;除数0F10H送ACCA
    MOVWF    ACCALO
    MOVLW    0X0F
    MOVWF    ACCAHI
    CALL    D_div    ;调用双字节除法子程序,求商
    END
 3  3字节浮点四则运算子程序
 3.1  浮点数加(减)法子程序
以下为浮点加(减)运算例程:

    LIST            p=16f877
    INCLUDE         p16f877.inc
    ACCALO         EQU     20        ;存放加数或减数的尾数
    ACCAHI         EQU    21
    EXPA        EQU     22        ;存放加数或减数阶码
    ACCBLO        EQU     23        ;存放被加数或被减数尾数以及和或差
    ACCBHI         EQU     24
    EXPB         EQU    25        ;存放被加数或被减数阶码
    ACCCLO        EQU     26        ;临时寄存器
    ACCCHI         EQU     27        ;临时寄存器
    ACCDLO        EQU     28        ;临时寄存器
    ACCDHI         EQU     29        ;临时寄存器
    TEMP         EQU     2A        ;临时寄存器
    TEMP1         EQU     30        ;临时寄存器
    TIMES         EQU     31        ;临时寄存器

    ORG             0X000
START    GOTO        MAIN
    ORG            0X0100
;**************浮点减法子程序****************
F_sub    CALL         NEG_A        ;求ACCA的补码,将减法转换为补码加法
;***********浮点加法子程序**************
F_add    CALL        SUBADJ        ;调子程序判断EXPB和EXPA的大小
    BTFSC         STATUS,Z    ;参与运算的两个数阶码相等?
    GOTO         PADD        ;是,求尾数的和
    BTFSC         STATUS,C    ;EXPB>EXPA?
    CALL         F_swap        ;是,ACCB与ACCA互换
    MOVF         EXPA,0        ;否,求取两者的差值
    SUBWF         EXPB
SCLOOP    CALL         SHFTSR        ;ACCB右移规格化
    INCFSZ         EXPB        ;EXPB=EXPA?        
    GOTO         SCLOOP        ;否,继续右移
    MOVF         EXPA,0        ;是,存和(差)的阶码
    MOVWF        EXPB
PADD    MOVF         ACCAHI,0    ;ACCAHI或ACCBHI
    IORWF         ACCBHI,0
    MOVWF         SIGN            ;存于SIGN寄存器
    MOVF        ACCBHI,0    ;暂存ACCBHI    
    MOVWF        EXPA
    CALL         D_add        ;尾数相加
    BTFSS         SIGN,7        ;ACCA和ACCB有负数?
               BTFSC         ACCBHI,7    ;否,把和的最高位和次高位同时进位?
    GOTO         ADD2        ;否,转ADD2
    BTFSS        ACCAHI,7    ;ACCA为负吗?
    GOTO        ADD3        ;ACCA和ACCB不同时为负,转ADD3
    BTFSS        EXPA,7        ;是,ACCB为负吗?
    GOTO        ADD3        
    BSF            STATUS,C    ;ACCA和ACCB同为负,带负号右移
    RRF            ACCBHI
    RRF            ACCBLO
    INCF            EXPB
ADD3    CLRF         ACCCHI        ;和(差)规格化
    CLRF         ACCCLO
    CALL         F_norm
    RETURN                    ;子程序返回
ADD2    BCF             STATUS,C    ;最高位次高位不同时进位,ACCB右移
    INCF         EXPB
    GOTO         SHFTR
SHFTSR     BCF             STATUS,C    ;ACCB带符号右移子程序
    BTFSC         ACCBHI,7
    BSF             STATUS,C
SHFTR      RRF             ACCBHI
    RRF             ACCBLO
    RETURN                    ;子程序返回
;********* ACCB、ACCA互换子程序************
F_swap    MOVF         ACCAHI,0    ;ACCAHI、ACCBHI互换
    MOVWF         TEMP
    MOVF         ACCBHI,0
    MOVWF         ACCAHI
    MOVF         TEMP,0
    MOVWF         ACCBHI
    MOVF         ACCALO,0    ;ACCALO、ACCBLO互换
    MOVWF         TEMP
    MOVF         ACCBLO,0
    MOVWF         ACCALO
    MOVF         TEMP,0
    MOVWF         ACCBLO
    MOVF         EXPA,0        ;EXPA、EXPB互换
    MOVWF         TEMP
    MOVF         EXPB,0
    MOVWF         EXPA
    MOVF         TEMP,0
    MOVWF         EXPB    
    RETURN
;*************比较EXPB、EXPA大小子程序*************
SUBADJ        MOVF        EXPA,0        ;EXPA异或EXPB,结果送C_DIV
    XORWF        EXPB,0
    MOVWF        C_DIV
    MOVF        EXPA,0        ;EXPB-EXPA
    SUBWF        EXPB,0
    BTFSS        C_DIV,7        ;EXPA和EXPB同号?
    RETURN                    ;是,进位位的值真确反映两者的大小,返回
    BTFSS        STATUS,C    ;否,进位位的值取反
    GOTO        CHANGEC
    BCF            STATUS,C
    RETURN
CHANGEC    BSF            STATUS,C
    RETURN
;***********浮点数规格化子程序****************
F_norm     MOVF         ACCBHI        ;ACCB=0?
    BTFSS         STATUS,Z
    GOTO         C_norm
    MOVF         ACCBLO
    BTFSC         STATUS,Z
    RETURN                    ;是,不需规格化,返回
C_norm    BTFSC        ACCBHI,7    ;否。ACCB为负?
     GOTO        C_norm2    
C_norm1    BTFSC         ACCBHI,6    ;为正。规格化完毕?
    RETURN                    ;ACCBHI.6=1,规格化结束
    CALL         SHFTSL        ;否。ACCB左移
    DECF         EXPB        ;EXPB减1
    GOTO         C_norm1        ;重新判断规格化完毕否?
C_norm2    BTFSS        ACCBHI,6    ;ACCB为负。规格化完毕否?
    RETURN                    ;ACCBHI.6=0,规格化结束
    BCF            STATUS,C    
    CALL        SHFTSL        ;否,ACCB左移
    BSF            ACCBHI,7    ;加符号
    DECF        EXPB        ;EXPB减1
    GOTO        C_norm2        ;重新判断规格化完毕否?
SHFTSL      BCF             STATUS ,C    ;ACCB左移子程序    
    RLF             ACCCLO        
    RLF             ACCCHI
    RLF             ACCBLO
    RLF             ACCBHI
    RETURN
【校验举例1】 0.0019531+(-0.00016594)=0.00178716
化为十六进制数:4000F8+A900F4
结果:7520F7
【校验举例2】 0.26222+3.5025=3.76478
化为十六进制数: 4321FF+701502
结果:787902
【例程】
MAIN        MOVLW        0X21            ;被加数的尾数4321H送ACCB
    MOVWF        ACCBLO
    MOVLW        0X43
    MOVWF        ACCBHI
        MOVLW        0XFF            ;被加数的阶码FFH送EXPB
        MOVWF        EXPB
    MOVLW        0X15            ;加数尾数7015H送ACCA
    MOVWF        ACCALO
    MOVLW        0X70
    MOVWF        ACCAHI
    MOVLW        0X02            ;加数阶码送EXPA
    MOVWF        EXPA
    CALL        F_add        ;调用浮点数加法子程序,求和
    END
 3.2  浮点数乘法子程序
以下为浮点数乘法的程序清单。
    LIST            p=16f877
    INCLUDE        p16f877.inc
    ACCALO         EQU     20        ;存放乘数尾数
    ACCAHI         EQU     21
    EXPA        EQU     22        ;存放乘数阶码
    ACCBLO         EQU     23        ;存放被乘数尾数和乘积高16位
    ACCBHI         EQU     24
    EXPB         EQU     25        ;存放被乘数阶码
    ACCCLO         EQU     26        ;存放乘积低16位
    ACCCHI         EQU     27        
    ACCDLO         EQU     28        ;临时寄存器
    ACCDHI         EQU     29        ;临时寄存器
    TEMP         EQU     2A        ;临时寄存器
    TEMP1         EQU     30        ;临时寄存器
    TIMES         EQU     31        ;临时寄存器
    SIGN         EQU     2B        ;存放乘积符号
    COUNT         EQU     2F        ;临时寄存器
    ACCEHI        EQU    30        ;临时寄存器
    ACCELO        EQU    31        ;临时寄存器

    ORG            0X0000
START    GOTO        MAIN
    ORG            0X0100
;***浮点乘法子程序,入口地址(ACCB、EXPB)×(ACCA、EXPA),出口地址ACCB、EXPB ***
F_mpy    CALL         S_SIGN        ;求取乘积的符号,并对负数取补
     CALL         SETUP        ;调用子程序将ACCB的值送ACCD
    CLRF         ACCCHI        ;清ACCC
    CLRF         ACCCLO
MLOOP    BCF             STATUS,C    ;清进位位
    RRF             ACCDHI        ;ACCD右移
    RRF             ACCDLO
    BTFSC         STATUS,C    ;判断是否需要相加
    CALL         D_add        ;加乘数至ACCB
    BCF             STATUS,C    ;清进位位
    RRF             ACCBHI        ;右移部分乘积
    RRF             ACCBLO
    RRF             ACCCHI
    RRF             ACCCLO
    DECFSZ         TEMP        ;乘法完成否?
    GOTO         MLOOP        ;否,继续循环
    MOVF         EXPA,0        ;是,乘数与被乘数阶码相加,得积的阶码
    ADDWF        EXPB
    MOVF         ACCBHI        ;ACCBHI=0?
    BTFSS         STATUS,Z
    GOTO         FINUP        ;否,转FINUP
    MOVF         ACCBLO        ;ACCB=0?
    BTFSS         STATUS ,Z
    GOTO         SHFT08        ;否,只有ACCBHI=0,转SHFT08
    MOVF         ACCCHI,0    ;ACCB=0,将乘积左移15位
    MOVWF         ACCBHI
    MOVF         ACCCLO,0
    MOVWF         ACCBLO
    BCF             STATUS,C
    RRF             ACCBHI
    RRF             ACCBLO
    MOVLW         .15            ;乘积阶码减15(十进制数)
    SUBWF         EXPB
    GOTO         FINUP
SHFT08    MOVF         ACCBLO,0    ;只有ACCBHI=0,乘积左移7位
    MOVWF         ACCBHI
    MOVF         ACCCHI,0
    MOVWF         ACCBLO
    BCF             STATUS,C
    RRF             ACCBHI
    RRF             ACCBLO
    MOVLW         .7            ;乘积阶码减7
    SUBWF         EXPB
FINUP    CALL         F_norm        ;对乘积进行规格化
    BTFSS         SIGN,7        ;确定乘积的符号
    GOTO         OVER        ;为正,乘法结束
    COMF         ACCCLO        ;为负,乘积取补
    INCF         ACCCLO
    BTFSC         STATUS,Z
    DECF         ACCCHI
    COMF         ACCCHI
    BTFSC         STATUS,Z
NEG_B    DECF         ACCBLO
    COMF         ACCBLO
    BTFSC         STATUS,Z
    DECF         ACCBHI
    COMF         ACCBHI
OVER    RETURN                    ;乘法结束,子程序返回
;********浮点乘除法运算确定结果符号子程序***********
S_SIGN    MOVF         ACCAHI,0    ;ACCAHI异或ACCBHI,结果送SIGN
    XORWF         ACCBHI,0
    MOVWF        SIGN            
    BTFSS         ACCBHI,7    ;ACCB为负?
    GOTO         CHEK_A        ;否,检查ACCA
    COMF         ACCBLO        ;是,ACCB取补
    INCF         ACCBLO
    BTFSC         STATUS,Z
    DECF         ACCBHI
    COMF         ACCBHI
CHEK_A        BTFSC         ACCAHI,7    ;ACCA为负?
    CALL        NEG_A        ;ACCA取补
    RETURN                    ;返回
;*********浮点运算结果规格化子程序*************
F_norm      MOVF         ACCBHI        ;ACCB=0?
    BTFSS         STATUS,Z
    GOTO         C_norm
    MOVF         ACCBLO
    BTFSC         STATUS,Z
    RETURN                    ;是,不需规格化,返回
C_norm    BTFSC        ACCBHI,7    ;否。ACCB为负?
     GOTO        C_norm2
C_norm1    BTFSC         ACCBHI,6    ;为正。规格化完毕?
    RETURN                    ;ACCBHI.6=1,规格化结束
    CALL         SHFTSL        ;否。ACCB左移
    DECF         EXPB        ;EXPB减1
    GOTO         C_norm1        ;重新判断规格化完毕否?
C_norm2    BTFSS        ACCBHI,6    ;ACCB为负。规格化完毕否?
    RETURN                    ;ACCBHI.6=0,规格化结束
    BCF            STATUS,C    
    CALL        SHFTSL        ;否,ACCB左移
    BSF            ACCBHI,7    ;加符号
    DECF        EXPB        ;EXPB减1
    GOTO        C_norm2        ;重新判断规格化完毕否?
SHFTSL     BCF             STATUS ,C    ;ACCB左移子程序    

⌨️ 快捷键说明

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