|
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
|