📄 16位乘除法.asm
字号:
MOVF NUMHI,0
MOVWF SQRTHI
MOVF NUMLO,0
MOVWF SQRTLO
BCF STATUS,C
RRF SQRTHI,1
RRF SQRTLO,1
RETLW 0
;***************16×16位定点数右移子程序***************
DIV2 BCF STATUS,C
RRF ACCBHI,0
MOVWF SQRTHI
RRF ACCBLO,0
MOVWF SQRTLO
RETLW 0
;*********16×16位定点数开方子程序**********
SQRT CALL INIT
SLOOP MOVF NUMLO,0
MOVWF ACCBLO
MOVF NUMHI,0
MOVWF ACCBHI
CALL D_DIVS
CALL D_ADD
CALL DIV2
DECFSZ COUNT,1
GOTO SLOOP
RETURN
;***********16×16位定点整数除法子程序*********
D_DIVS CALL SETUP
CLRF ACCCHI
CLRF ACCCLO
DLOOP BCF STATUS,C
RLF ACCDLO
RLF ACCDHI
RLF ACCCLO
RLF ACCCHI
MOVF ACCAHI,0
SUBWF ACCCHI,0
BTFSS STATUS,Z
GOTO NOCHK
MOVF ACCALO,0
SUBWF ACCCLO,0
NOCHK BTFSS STATUS,C
GOTO NOGO
MOVF ACCALO,0
SUBWF ACCCLO,1
BTFSS STATUS,C
DECF ACCCHI,1
MOVF ACCAHI,0
SUBWF ACCCHI,1
BSF STATUS,C
NOGO RLF ACCBLO
RLF ACCBHI
DECFSZ TEMP
GOTO DLOOP
RETLW 0
;****************************************
SETUP MOVLW .16
MOVWF TEMP
MOVF ACCBHI,0
MOVWF ACCDHI
MOVF ACCBLO,0
MOVWF ACCDLO
CLRF ACCBHI
CLRF ACCBLO
RETLW 0
;**********16×16位定点数取补子程序**************
NEG_A COMF ACCALO,1
INCF ACCALO,1
BTFSC STATUS,Z
DECF ACCAHI,1
COMF ACCAHI,1
RETLW 0
;*************16×16位定点数加法子程序**************
D_ADD MOVF ACCALO,0
ADDWF ACCBLO,1
BTFSC STATUS,C
INCF ACCBHI,1
MOVF ACCAHI,0
ADDWF ACCBHI,1
RETLW 0
;****************************************
【校验举例】 被开方数2910H(十六进制)
10512(十进制)
求得平方根:66H(十六进制)
102(十进制)
MAIN NOP
MOVLW 0X29
MOVWF NUMHI
MOVL7W 0X10
MOVWF NUMLO ;被开方数赋值
CALL SQRT ;调用开方子程序
NOP ;开方完毕
END
7 浮点数开方程序
如果被开方数是浮点数格式,代入的迭代初值也是浮点数格式,并且用浮点除法(浮点数的除以2操作可以由阶码减1得到)和浮点加法进行迭代运算,就是浮点数开方的基本思路。
以下为浮点数开方的程序清单(其中包含校验程序部分)。该程序中包含浮点数加法程序和浮点数除法程序,这些程序与前面章节列出的程序完全相同,不再列出。
LIST P=16f877
INCLUDE p16f877.inc
;****************************************
;此子程序是16尾数,8位阶码开方程序
;入口条件:浮点数存放在ACCBHI和ACCBLO EXPB单元中.
;出口条件:结果放在ACCBHI和ACCBLO EXPB单元中.
;迭代次数由LUPCNT的地址值决定
;用CALL SQRTF指令调用,
;内含浮点除程序,浮点加减程序
;****************************************
ACCALO EQU 20H
ACCAHI EQU ACCALO +1
EXPA EQU ACCALO +2
ACCBLO EQU ACCALO +3
ACCBHI EQU ACCALO +4
EXPB EQU ACCALO +5
ACCCLO EQU ACCALO +6
ACCCHI EQU ACCALO +7
ACCDLO EQU ACCALO +8
ACCDHI EQU ACCALO +9
TEMP EQU ACCALO +0A
TEMP1 EQU ACCALO +0B
TIMES EQU ACCALO +0C
SIGN EQU ACCALO +0D
COUNT EQU ACCALO +0E
C_MUL EQU ACCALO +0F
C_DIV EQU ACCALO +10
FPOL EQU ACCALO +11 ;符号放置位
NUMLO EQU FPOL+1
NUMHI EQU FPOL+2
NUMM EQU FPOL+4
LUPCNT EQU .10
CONSTANT C=0
CONSTANT Z=2
CONSTANT MODEL16=1
CONSTANT FALSE=0
;****************************************
ORG 0X0000
NOP
GOTO MAIN
ORG 0X0010
;****************************************
INIT1 DECF EXPB ;假设迭代根的初始值为其原值的一半
MOVF ACCBHI,W
MOVWF ACCAHI
MOVF ACCBLO,W
MOVWF ACCALO
MOVF EXPB,W
MOVWF EXPA
RETLW 0
SQRTF MOVLW LUPCNT
MOVWF COUNT
MOVF ACCBHI,W
MOVWF NUMHI
MOVF ACCBLO,W
MOVWF NUMLO
MOVF EXPB,W
MOVWF NUMM ;存储被开方的数
BTFSC ACCBHI,7
GOTO TIQIAN ;如果被开方数是个负数,则返回一极小数
CALL INIT1
SLOOP1 MOVF NUMLO,0
MOVWF ACCBLO
MOVF NUMHI,0
MOVWF ACCBHI
MOVF NUMM,0
MOVWF EXPB
CALL FDIV
CALL F_add
CALL INIT1
DECFSZ COUNT,1
GOTO SLOOP1
RETURN
TIQIAN MOVLW 0X40
MOVWF ACCBHI
CLRF ACCBLO
MOVLW 0X80
MOVWF EXPB ;如果被开方数是一个负数,返回一个极小的浮点数
RETURN
;***浮点加子程序F_add详细的程序语句请参考前面章节***
;***浮点数除法子程序FDIV详细的程序语句请参考前面章节***
【校验举例】 被开方数55AAH,02H (浮点数)
求得平方根:68B6H,01H (浮点数)
MAIN NOP
MOVLW 0X55
MOVWF ACCBHI
MOVLW 0XAA
MOVWF ACCBLO ;被开方数的尾数55AAH赋值
MOVLW 0X02
MOVWF EXPB ;被开方数的阶码02H赋值
CALL SQRTF ;调用浮点开方子程序
NOP ;开方完毕,结果在ACCBHI、ACCBLO、EXPB
END
8 小数点显示位置确定子程序
在实际应用中,往往需要将一个浮点数表示的十进制数用数码管显示出来。当用户调用浮点数至BCD码子程序FtoBCD将这个浮点数转换成BCD码后,除了可以得到5位BCD码外,C_MUL和C_DIV寄存器中还有一个值用于确定哪个数码管该显示小数点。例如,设某浮点数调用译码子程序后,得到以下数值:012345(BCD),C_MUL=07,C_DIV=0,那么数码管显示的值应该为:0.0012345,1号数码管除了要显示0外,还要将小数点显示出来。以下子程序将完成这一功能。此外,一般而言,工程应用和实验中,多数要求显示4位有效数字,其显示范围在0.001~9999(符号没显示,如有需要,请读者自己添上)。如果要求显示数据超过9999,则4个LED显示“1111”;如果要求显示数据小于“0.001”,则4个LED显示“0000”(如果实际要求显示多于4位有效数字,则读者可以对本程序作相应的修改,就可以满足要求)。本子程序入口条件和出口条件分别如下:
入口条件:ACCCHI1、ACCCLO1、ACCDHI1、ZUO、YOU;
出口条件:DISP1、DISP2、DISP3、DISP4、LEDDOT(DISP1、DISP2、DISP3、DISP4用于存放显示的数字,LEDDOT用于存放小数点的位置)。
注意,该子程序的入口条件和FtoBCD子程序的出口条件有如下对应关系:
ACCCHI1与ACCCHI对应,ACCCLO1与ACCCLO对应,ACCDHI1与ACCDHI对应,ZUO与C_MUL对应,YOU与C_DIV对应
用户在调用FtoBCD子程序后,可以用下面一段语句与该程序实现接口。
CALL FtoBCD
MOVF ACCCHI,W
MOVWF ACCCHI1
MOVF ACCCLO,W
MOVWF ACCCLO1
MOVF ACCDHI,W
MOVWF ACCDHI1
MOVF C_MUL,W
MOVWF ZUO
MOVF C_DIV,W
MOVWF YOU
CALL TESTDOT
本子程序的程序清单如下:
;**********小数点位置及显示寄存器值确定子程序************
TESTDOT BANKSEL LEDDOT
CLRF LEDDOT ;清除小数点位置寄存器
MOVF ZUO,W
MOVWF C_MUL1
MOVF YOU,W
BTFSS STATUS,Z
GOTO CHAOCHU1
MOVF ZUO,W
BTFSC STATUS,Z
GOTO CHAOCHU1 ;C_DIV>0或C_MUL=0,表示浮点数超出显示
;范围上限,转移到过量程处理
MOVF ZUO,W
SUBLW 0X07
BTFSS STATUS,C
GOTO TAIXIAO ;C_MUL>7,超出显示范围下限,转移处理(改
;变与C_MUL比较的立即数的大小,可以改变
;下限)
MOVF ZUO,W
SUBLW 0X01
BTFSC STATUS,Z
GOTO ZHUANG1 ;C_MUL=1,表示小数点左移1位,能够显示前
;4位(ACCCHI低半字节中始终有1位),转移处理
MOVF ZUO,W ;同理可以对左移2~7位处理
SUBLW 0X02
BTFSC STATUS,Z
GOTO ZHUANG2
MOVF ZUO,W
SUBLW 0X03
BTFSC STATUS,Z
GOTO ZHUANG3
MOVF ZUO,W
SUBLW 0X04
BTFSC STATUS,Z
GOTO ZHUANG4
MOVF ZUO,W
SUBLW 0X05
BTFSC STATUS,Z
GOTO ZHUANG5
MOVF ZUO,W
SUBLW 0X06
BTFSC STATUS,Z
GOTO ZHUANG6
MOVF ZUO,W
SUBLW 0X07
BTFSC STATUS,Z
GOTO ZHUANG7
CHAOCHU1 MOVLW 0X01
MOVWF DISP1
MOVWF DISP2
MOVWF DISP3
MOVWF DISP4
MOVLW 0XFF
MOVWF LEDDOT ;不显示小数点
RETURN ;超出上限时,DSP1、 DSP2、 DSP3、 DSP4中赋
;1,显示“1111”
TAIXIAO MOVLW 0X00
MOVWF DISP1
MOVWF DISP2
MOVWF DISP3
MOVWF DISP4
MOVLW 0X01
MOVWF LEDDOT ;小数点的位置在第一位
RETURN ;超出下限,显示"0.000"
ZHUANG1 CALL BIAO ;C_MUL=1~4时,可调用标准赋值模块对
;DSP1、 DSP2、DSP3、 DSP4赋值
MOVLW 0X04
MOVWF LEDDOT ;C_MUL=1时,小数点的位置在第4位
RETURN
ZHUANG2 CALL BIAO
MOVLW 0X03
MOVWF LEDDOT ;C_MUL=2时,小数点的位置在第3位
RETURN
ZHUANG3 CALL BIAO
MOVLW 0X02
MOVWF LEDDOT ;C_MUL=3时,小数点的位置在第2位
RETURN
Z
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -