📄 16×16位定点数乘法子程序.txt
字号:
;【校验举例2】 16405×13089=214725045(十进制)
;化为十六进制数:4015H×3321H
;结果:0CCC71B5H(十六进制)
;2.2 16×16位定点数乘法子程序
;子程序采用部分积右移加法实现乘法运算。乘数和被乘数分别为16位二进制
;有符号数(均采用补码表示,第16位为符号位),积为32位二进制有符号数,
;第32位为符号位。子程序的入口条件和出口条件如下:
;入口条件:被乘数存放在ACCBHI和ACCBLO单元中,
; 乘数存放在ACCAHI和ACCALO单元中。
;出口条件:积存放在ACCBHI、ACCBLO、ACCCHI和ACCCLO单元中,ACCB为高16位,
;ACCC为低16位。
;以下为本子程序的程序清单:
LIST p=16f877
INCLUDE p16f877.inc
ACCALO EQU 20h ;存放乘数低8位
ACCAHI EQU 21h ;存放乘数高8位
ACCBLO EQU 23h ;存放被乘数低8位和乘积第16~23位
ACCBHI EQU 24h ;存放被乘数高8位和乘积第24~31位
ACCCLO EQU 26h ;存放乘积低8位
ACCCHI EQU 27h ;存放乘积高8位
ACCDLO EQU 28h ;临时寄存器
ACCDHI EQU 29h ;临时寄存器
TEMP EQU 2Ah ;临时寄存器
SIGN EQU 2Bh ;存放乘积的符号
FULL EQU 2C ;2C.0存放进位
ORG 0X0000
START GOTO MAIN
;***16×16位乘法子程序,入口地址ACCB×ACCA,出口地址ACCB和ACCC ***
ORG 0X0100
D_mpy CALL S_SIGN ;求取乘积的符号,并对负数取补
CALL SETUP ;调用子程序,将ACCB的值送ACCD
INCF TEMP
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 ;否,继续求乘积
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 ;子程序返回
;***双字节加法子程序,入口地址ACCB+ACCA,出口地址ACCB***
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 ;子程序返回
;*******乘法运算确定结果符号判断子程序******
S_SIGN MOVF ACCAHI,0 ;ACCAHI异或ACCBHI,结果送SIGN单元
XORWF ACCBHI,0
MOVWF SIGN
BTFSS ACCBHI,7 ;ACCB为负吗?
GOTO CHEK_A ;否,检查ACCA
CALL NEG_B ;是,求取ACCB绝对值
CHEK_A BTFSC ACCAHI,7 ;ACCA为负吗?
CALL NEG_A ;ACCA为负,求取ACCA绝对值,
;见双字节加法程序
RETURN ;ACCA和ACCB均为正,返回
NEG_A COMF ACCALO ;ACCALO取反加1
INCF ACCALO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCAHI ;有,ACCAHI减1,再取反
COMF ACCAHI ;否则ACCAHI直接取反
RETURN ;子程序返回
MAIN MOVLW 0X15 ;被乘数4015H送ACCB
MOVWF ACCBLO
MOVLW 0X40
MOVWF ACCBHI
MOVLW 0X21 ;乘数3321H送ACCA
MOVWF ACCALO
MOVLW 0X33
MOVWF ACCAHI
CALL D_mpy ;调用双字节乘法子程序,求积
GOTO $
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -