📄 16位乘除法.asm
字号:
RLF ACCCLO
RLF ACCCHI
RLF ACCBLO
RLF ACCBHI
RETURN
【校验举例1】 0.0019531×(-0.00016594)=-0.000000324
化为十六进制数:4000F8×A900F4
结果:A900EB
【校验举例2】 0.26222×3.5025=0.91842
化为十六进制数: 4321FF×701502
结果: 758F00
【例程】
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_mpy ;调用浮点数乘法子程序,求积
END
3.3 浮点数除法子程序
以下为浮点数除法子程序清单。
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 ;临时寄存器
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_div CALL S_SIGN ;确定商的符号,并将负数取补
CLRF ACCCHI ;初始化ACCC寄存器
CLRF ACCCLO
CALL F_norm ;规格化ACCB
CLRF ACCCLO
CLRF ACCCHI
CLRF TIMES
MOVF ACCAHI ;除数为零?
BTFSS STATUS,Z
GOTO FD0 ;否,求商
MOVF ACCALO
BTFSC STATUS,Z
RETLW 01 ;是,返回
FD0 CALL NEG_A ;除数取补
FD1 MOVF ACCBHI,0 ;ACCBHI送ACCDLO
MOVWF ACCDLO
CALL D_add1 ;被除数尾数大于除数尾数?
BTFSS STATUS,C
GOTO FD2
RRF1 BCF STATUS,C ;是,被除数右移规格化,直到小于除数为止
RRF ACCBHI
RRF ACCBLO
INCF TIMES
RRF ACCCHI
BCF STATUS,C
GOTO FD1
FD2 CALL DDIV ;否,调用双字节除法子程序,求商的尾数
MOVF TIMES,0 ;根据右移规格化次数调整ACCB阶码
ADDWF EXPB
MOVF EXPA,0 ;求商的阶码
SUBWF EXPB
CALL F_norm ;商规格化
BTFSC SIGN,7 ;商为负?
CALL NEG_B ;是,取补
CALL NEG_A ;除数还原
RETURN ;浮点数除法完成,返回
;***********双字节纯小数除法子程序***************
DDIV MOVLW 0X0F ;初始化ACCDHI
MOVWF ACCDHI
DV1 BCF STATUS,C
RLF ACCCLO ;左移商
RLF ACCCHI
RLF ACCBLO ;左移余数
RLF ACCBHI
MOVF STATUS,0 ;暂存STATUS寄存器
MOVWF ACCDLO
MOVF ACCBHI,0 ;ACCBHI送TEMP1
MOVWF TEMP1
MOVF ACCALO,0 ;ACCB-ACCA
ADDWF ACCBLO,0
MOVWF TEMP
BTFSC STATUS,C
INCF TEMP1
MOVF ACCAHI,0
ADDWF TEMP1,0
BTFSC ACCDLO,0 ;左移余数时移出来的数为1?
GOTO DV2
TESTC BTFSS STATUS,C ;是,再判断ACCB尾数是否大于ACCA
GOTO DV3
DV2 MOVWF ACCBHI ;是,余数送ACCB
MOVF TEMP,0
MOVWF ACCBLO
INCF ACCCLO ;商加1
DV3 DECFSZ ACCDHI ;商求取完毕?
GOTO DV1
MOVF ACCCHI,0 ;是,将商送ACCB
MOVWF ACCBHI
MOVF ACCCLO,0
MOVWF ACCBLO
RETLW 00
;**********本子程序用于判断比较ACCB与ACCA的大小**********
D_add1 MOVF ACCALO,0 ;加数、被加数低半字节相加
ADDWF ACCBLO,0
BTFSC STATUS,C ;有进位?
INCF ACCDLO ;ACCD低半字节加1
MOVF ACCAHI,0 ;ACCAHI+ACCDLO
ADDWF ACCDLO
RETLW 0 ;子程序返回
;****************************************
SETUP MOVLW .15
MOVWF TEMP
MOVF ACCBHI,0
MOVWF ACCDHI
MOVF ACCBLO,0
MOVWF ACCDLO
CLRF ACCBHI
CLRF ACCBLO
RETLW 0
;*************** ACCA取补子程序*************
NEG_A COMF ACCALO ;ACCALO取反加1
INCF ACCALO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCAHI ;有,ACCAHI减1,再取反
COMF ACCAHI ;否,ACCAHI直接取反
RETLW 0
;********* ACCB取补子程序*************
NEG_B DECF ACCBLO ;ACCBLO取反加1
COMF ACCBLO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCBHI ;有,ACCBHI减1,再取反
COMF ACCBHI ;否,ACCBHI直接取反
RETLW 0
;*********浮点乘除法运算确定结果符号子程序**********
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为负,取补
RETLW 0 ;ACCA和ACCB均为负,返回
;************浮点运算结果规格化子程序***************
F_norm MOVF ACCBHI ;ACCB=0?
BTFSS STATUS,Z
GOTO C_norm
MOVF ACCBLO
BTFSC STATUS,Z
RETLW 0 ;是,不需规格化,返回
C_norm BTFSC ACCBHI,7 ;否。ACCB为负?
GOTO C_norm2
C_norm1 BTFSC ACCBHI,6 ;为正。规格化完毕?
RETLW 0 ;ACCBHI.6=1,规格化结束
CALL SHFTSL ;否。ACCB左移
DECF EXPB ;EXPB减1
GOTO C_norm1 ;重新判断规格化完毕否?
C_norm2 BTFSS ACCBHI,6 ;ACCB为负。规格化完毕否?
RETLW 0 ;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
RETLW 0
【校验举例1】 0.0019531÷(-0.00016594)=-12.7699
化为十六进制数:4000F8÷A900F4
结果:A1D704
【校验举例2】 0.26222÷3.5025=0.074867
化为十六进制数: 4321FF÷701502
结果:4CA9FD
【例程】
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_div ;调用浮点数除法子程序,求商
END
4 定点数与浮点数转换程序
4.1 定点数转换成浮点数
本子程序的功能是将双字节定点整数(十六进制)转换为3字节浮点数,其转换数值范围:-32768~32767,入口条件和出口条件如下:
入口条件:ACCBHI、ACCBLO
出口条件:ACCBHI、ACCBLO、EXPB
以下为定点整数转换成浮点数的程序清单。
LIST p=16f877
INCLUDE p16f877.inc
ACCBLO EQU 23 ;存放定点整数和转换后浮点数的尾数
ACCBHI EQU 24
EXPB EQU 25 ;存放转换后浮点数的阶码
ACCCLO EQU 26 ;临时寄存器
ACCCHI EQU 27 ;临时寄存器
ACCDLO EQU 28 ;临时寄存器
ACCDHI EQU 29 ;临时寄存器
SIGN EQU 2B ;存放被转换数的符号
ORG 0X0000
START GOTO MAIN
ORG 0X0100
;*********双字节定点整数到浮点数转换子程序***********
DtoF CLRF SIGN ;根据被转换数确定结果的符号,对负数取补
BTFSS ACCBHI,7
GOTO INTF1
BSF SIGN,7
CALL NEG_B
INTF1 MOVLW .15 ;初始化EXPB
MOVWF EXPB
CLRF ACCCHI
CLRF ACCCLO
CALL F_norm ;对ACCB进行规格化
BTFSS SIGN,7 ;结果为负?
GOTO DtoF1
CALL NEG_B ;是,求补
DtoF1 RETURN
;**************浮点数规格化子程序**************
F_norm MOVF ACCBHI ;ACCB=0?
BTFSS STATUS,Z
GOTO C_norm
MOVF ACCBLO
BTFSC STATUS,Z
RETLW 0 ;是,不需规格化,返回
C_norm BTFSC ACCBHI,7 ;否。ACCB为负?
GOTO C_norm2
C_norm1 BTFSC ACCBHI,6 ;为正。规格化完毕?
RETLW 0 ;ACCBHI.6=1,规格化结束
CALL SHFTSL ;否。ACCB左移
DECF EXPB ;EXPB减1
GOTO C_norm1 ;重新判断规格化完毕否?
C_norm2 BTFSS ACCBHI,6 ;ACCB为负。规格化完毕否?
RETLW 0 ;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
RETLW 0
【校验举例1】 19531(十进制)
化为十六进制数:4C4BH
结果:4C4B0FH
【校验举例2】 2622(十进制)
化为十六进制数: 0A3EH
结果:51F00CH
【例程】
MAIN MOVLW 0X4B ;被转换数4C4BH送ACCB
MOVWF ACCBLO
MOVLW 0X4C
MOVWF ACCBHI
CALL DtoF ;调用定点数至浮点数转换子程序
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -