📄 浮点加(减)运算例程.txt
字号:
;【校验举例2】 0.26222+3.5025=3.76478
;化为十六进制数: 4321FF+701502
;结果:787902
;以下为浮点加(减)运算例程:
LIST p=16f877
INCLUDE p16f877.inc
ACCALO EQU 20H ;存放加数或减数的尾数
ACCAHI EQU 21H
EXPA EQU 22H ;存放加数或减数阶码
ACCBLO EQU 23H ;存放被加数或被减数尾数以及和或差
ACCBHI EQU 24H
EXPB EQU 25H ;存放被加数或被减数阶码
ACCCLO EQU 26H ;临时寄存器
ACCCHI EQU 27H ;临时寄存器
ACCDLO EQU 28H ;临时寄存器
ACCDHI EQU 29H ;临时寄存器
TEMP EQU 2AH ;临时寄存器
C_DIV EQU 2BH
SIGN EQU 2CH
FULL EQU 2D ;22.0存放进位
TEMP1 EQU 30H ;临时寄存器
TIMES EQU 31H ;临时寄存器
ORG 0X000
START GOTO MAIN
ORG 0X0100
;**************浮点减法子程序****************
F_sub CALL NEG_A ;求ACCA的补码,将减法转换为补码加法
NEG_A COMF ACCALO ;ACCALO取反加1
INCF ACCALO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCAHI ;有,ACCAHI减1,再取反
COMF ACCAHI ;否,ACCAHI直接取反
RETLW 0
;***********浮点加法子程序**************
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 ;子程序返回
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'
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
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 ;调用浮点数加法子程序,求和
goto $
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -