📄 浮点数乘法的程序.txt
字号:
;【校验举例2】 0.26222×3.5025=0.91842
;化为十六进制数: 4321FF×701502
;结果:758F00
;以下为浮点数乘法的程序清单。
LIST p=16f877
INCLUDE p16f877.inc
ACCALO EQU 20h ;存放乘数尾数
ACCAHI EQU 21h
EXPA EQU 22h ;存放乘数阶码
ACCBLO EQU 23h ;存放被乘数尾数和乘积高16位
ACCBHI EQU 24h
EXPB EQU 25h ;存放被乘数阶码
ACCCLO EQU 26h ;存放乘积低16位
ACCCHI EQU 27h
ACCDLO EQU 28h ;临时寄存器
ACCDHI EQU 29h ;临时寄存器
TEMP EQU 2Ah ;临时寄存器
FULL EQU 2B ;22.0存放进位
TEMP1 EQU 30h ;临时寄存器
TIMES EQU 31h ;临时寄存器
SIGN EQU 2Bh ;存放乘积符号
COUNT EQU 2Fh ;临时寄存器
ACCEHI EQU 30h ;临时寄存器
ACCELO EQU 31h ;临时寄存器
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 ;返回
NEG_A COMF ACCALO ;ACCALO取反加1
INCF ACCALO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCAHI ;有,ACCAHI减1,再取反
COMF ACCAHI ;否,ACCAHI直接取反
RETLW 0
D_add MOVF ACCALO,0 ;ACCB和ACCA低半字节相加
ADDWF ACCBLO
BTFSC STATUS,C ;有进位否?
goto $+6 ;有,
MOVF ACCAHI,0 ;ACCA、ACCB高半字节相加
ADDWF ACCBHI
BTFSC STATUS,C
BSF FULL,0
RETURN ;子程序返回
MOVFW ACCBHI ;ACCB高字节加1,再加ACCAHI
ADDLW 1h
BTFSC STATUS,C ;有进位否?
BSF FULL,0
MOVWF ACCBHI
GOTO $-D'10'
SETUP MOVLW .15 ;初始化TEMP寄存器
MOVWF TEMP
MOVF ACCBHI,0 ;ACCB送ACCD
MOVWF ACCDHI
MOVF ACCBLO,0
MOVWF ACCDLO
CLRF ACCBHI ;清ACCB
CLRF ACCBLO
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
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 ;调用浮点数乘法子程序,求积
goto $
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -