|
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左移子程序 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 |