?? 浮點數乘法的程序.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 + -