MCS51 浮点运算子程序库文档格式.docx
- 文档编号:16637616
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:43
- 大小:29.09KB
MCS51 浮点运算子程序库文档格式.docx
《MCS51 浮点运算子程序库文档格式.docx》由会员分享,可在线阅读,更多相关《MCS51 浮点运算子程序库文档格式.docx(43页珍藏版)》请在冰豆网上搜索。
用户只要不在工作区中存放无关的或非消耗性的信息,程序就具有较好的
透明性。
6.子程序调用范例:
由于本程序库特别注意了各子程序接口的相容性,很容易采用
积木方式(或流水线方式)完成一个公式的计算。
以浮点运算为例:
计算y=Ln√|Sin(ab/c+d)|
已知:
a=-123.4;
b=0.7577;
c=56.34;
d=1.276;
它们分别存放在30H、33H、36H、
39H开始的连续三个单元中。
用BCD码浮点数表示时,分别为a=831234H;
b=007577H;
c=025634H;
d=011276H。
求解过程:
通过调用BTOF子程序,将各变量转换成二进制浮点操作数,再进行各
种运算,最后调用FTOB子程序,还原成十进制形式,供输出使用。
程序如下:
TEST:
MOVR0,#39H;
指向BCD码浮点操作数d
LCALLBTOF;
将其转换成二进制浮点操作数
MOVR0,#36H;
指向BCD码浮点操作数c
MOVR0,#33H;
指向BCD码浮点操作数b
MOVR0,#30H;
指向BCD码浮点操作数a
MOVR1,#33H;
指向二进制浮点操作数b
LCALLFMUL;
进行浮点乘法运算
MOVR1,#36H;
指向二进制浮点操作数c
LCALLFDIV;
进行浮点除法运算
MOVR1,#39H;
指向二进制浮点操作数d
LCALLFADD;
进行浮点加法运算
LCALLFSIN;
进行浮点正弦运算
LCALLFABS;
进行浮点绝对值运算
LCALLFSQR;
进行浮点开平方运算
LCALLFLN;
进行浮点对数运算
LCALLFTOB;
将结果转换成BCD码浮点数
STOP:
LJMPSTOP
END
运行结果,[R0]=804915H,即y=-0.4915,比较精确的结果应该是-0.491437。
(1)标号:
FSDT功能:
浮点数格式化
入口条件:
待格式化浮点操作数在[R0]中。
出口信息:
已格式化浮点操作数仍在[R0]中。
影响资源:
PSW、A、R2、R3、R4、位1FH堆栈需求:
6字节
FSDT:
LCALLMVR0;
将待格式化操作数传送到第一工作区中
LCALLRLN;
通过左规完成格式化
LJMPMOV0;
将已格式化浮点操作数传回到[R0]中
(2)标号:
FADD功能:
浮点数加法
被加数在[R0]中,加数在[R1]中。
OV=0时,和仍在[R0]中,OV=1时,溢出。
PSW、A、B、R2~R7、位1EH、1FH堆栈需求:
FADD:
CLRF0;
设立加法标志
SJMPAS;
计算代数和
(3)标号:
FSUB功能:
浮点数减法
被减数在[R0]中,减数在[R1]中。
OV=0时,差仍在[R0]中,OV=1时,溢出。
6字节
FSUB:
SETBF0;
设立减法标志
AS:
LCALLMVR1;
计算代数和。
先将[R1]传送到第二工作区
MOVC,F0;
用加减标志来校正第二操作数的有效符号
RRCA
XRLA,@R1
MOVC,ACC.7
ASN:
MOV1EH,C;
将第二操作数的有效符号存入位1EH中
XRLA,@R0;
与第一操作数的符号比较
RLCA
MOVF0,C;
保存比较结果
LCALLMVR0;
将[R0]传送到第一工作区中
LCALLAS1;
在工作寄存器中完成代数运算
MOV0:
INCR0;
将结果传回到[R0]中的子程序入口
INCR0
MOVA,R4;
传回尾数的低字节
MOV@R0,A
DECR0
MOVA,R3;
传回尾数的高字节
MOVA,R2;
取结果的阶码
MOVC,1FH;
取结果的数符
MOVACC.7,C;
拼入阶码中
CLRACC.7;
不考虑数符
CLROV;
清除溢出标志
CJNEA,#3FH,MV01;
阶码是否上溢?
SETBOV;
设立溢出标志
MV01:
MOVA,@R0;
取出带数符的阶码
RET
MVR0:
将[R0]传送到第一工作区中的子程序
MOVC,ACC.7;
将数符保存在位1FH中
MOV1FH,C
MOVC,ACC.6;
将阶码扩充为8bit补码
MOVACC.7,C
MOVR2,A;
存放在R2中
MOVA,@R0;
将尾数高字节存放在R3中
MOVR3,A
将尾数低字节存放在R4中
MOVR4,A
DECR0;
恢复数据指针
MVR1:
MOVA,@R1;
将[R1]传送到第二工作区中的子程序
将数符保存在位1EH中
MOV1EH,C
MOVR5,A;
存放在R5中
INCR1
MOVA,@R1;
将尾数高字节存放在R6中
MOVR6,A
将尾数低字节存放在R7中
MOVR7,A
DECR1;
DECR1
AS1:
MOVA,R6;
读取第二操作数尾数高字节
ORLA,R7
JZAS2;
第二操作数为零,不必运算
读取第一操作数尾数高字节
ORLA,R4
JNZEQ1
MOVA,R6;
第一操作数为零,结果以第二操作数为准
MOVA,R7
MOVA,R5
MOVR2,A
MOVC,1EH
AS2:
RET
EQ1:
MOVA,R2;
对阶,比较两个操作数的阶码
XRLA,R5
JZAS4;
阶码相同,对阶结束
JBACC.7,EQ3;
阶符互异
阶符相同,比较大小
CLRC
SUBBA,R5
JCEQ4
EQ2:
CLRC;
第二操作数右规一次
尾数缩小一半
INCR5;
阶码加一
ORLA,R6;
尾数为零否?
JNZEQ1;
尾数不为零,继续对阶
尾数为零,提前结束对阶
MOVR5,A
SJMPAS4
EQ3:
判断第一操作数阶符
JNBACC.7,EQ2;
如为正,右规第二操作数
EQ4:
CLRC
LCALLRR1;
第一操作数右规一次
ORLA,R3;
不为零,继续对阶
MOVA,R5;
AS4:
JBF0,AS5;
尾数加减判断
尾数相加
ADDA,R7
MOVA,R3
ADDCA,R6
JNCAS2
LJMPRR1;
有进位,右规一次
AS5:
比较绝对值大小
MOVA,R4
SUBBA,R7
MOVB,A
MOVA,R3
SUBBA,R6
JCAS6
MOVR4,B;
第一尾数减第二尾数
LJMPRLN;
结果规格化
AS6:
CPL1FH;
结果的符号与第一操作数相反
CLRC;
结果的绝对值为第二尾数减第一尾数
SUBBA,R4
MOVA,R6
SUBBA,R3
RLN:
MOVA,R3;
浮点数规格化
ORLA,R4;
JNZRLN1
MOVR2,#0C1H;
阶码取最小值
RET
RLN1:
MOVA,R3
JBACC.7,RLN2;
尾数最高位为一否?
不为一,左规一次
LCALLRL1
SJMPRLN;
继续判断
RLN2:
CLROV;
规格化结束
RL1:
MOVA,R4;
第一操作数左规一次
RLCA;
尾数扩大一倍
DECR2;
阶码减一
CJNER2,#0C0H,RL1E;
阶码下溢否?
CLRA
MOVR3,A;
阶码下溢,操作数以零计
MOVR2,#0C1H
RL1E:
CLROV
RR1:
RRCA;
INCR2;
清溢出标志
CJNER2,#40H,RR1E;
阶码上溢否?
MOVR2,#3FH;
阶码溢出
SETBOV
RR1E:
(4)标号:
FMUL功能:
浮点数乘法
被乘数在[R0]中,乘数在[R1]中。
OV=0时,积仍在[R0]中,OV=1时,溢出。
FMUL:
MOVA,@R0
XRLA,@R1;
比较两个操作数的符号
MOV1FH,C;
保存积的符号
LCALLMUL0;
计算积的绝对值
将结果传回到[R0]中
MUL0:
将[R1]传送到第二工作区中
MUL1:
第一尾数为零否?
JZMUL6
第二尾数为零否?
JZMUL5
MOVA,R7;
计算R3R4×
R6R7-→R3R4
MOVB,R4
MULAB
MOVA,B
XCHA,R7
MOVB,R3
ADDCA,B
XCHA,R4
MOVB,R6
ADDCA,R4
XCHA,R3
ADDA,R4
ADDCA,R3
JBACC.7,MUL2;
积为规格化数否?
左规一次
MUL2:
MOVA,R7
JNBACC.7,MUL3
INCR4
JNZMUL3
INCR3
MOVR3,#80H
INCR2
MUL3:
求积的阶码
ADDA,R5
MD:
MOVR2,A;
阶码溢出判断
JBACC.7,MUL4
JNBACC.6,MUL6
阶码上溢,设立标志
MUL4:
JBACC.6,MUL6
MUL5:
CLRA;
结果清零(因子为零或阶码下溢)
MOVR2,#41H
MUL6:
(5)标号:
FDIV功能:
浮点数除法
被除数在[R0]中,除数在[R1]中。
OV=0时,商仍在[R0]中,OV=1时,溢出。
5字节
FDIV:
INCR0
ORLA,@R0
JNZDIV1
MOV@R0,#41H;
被除数为零,不必运算
CLROV
DIV1:
INCR1
MOVA,@R1
INCR1
ORLA,@R1
DECR1
JNZDIV2
除数为零,溢出
DIV2:
保存结果的符号
LCALLMVR1;
LCALLDIV3;
调用工作区浮点除法
回传结果
DIV3:
比较尾数的大小
JCDIV4
被除数右规一次
SJMPDIV3
DIV4:
借用R0R1R2作工作寄存器
XCHA,R0;
清零并保护之
PUSHACC
XCHA,R1
MOVA,R2
MOVB,#10H;
除法运算,R3R4/R6R7-→R0R1
DIV5:
MOVA,R1
MOVR1,A
MOVA,R0
MOVR0,A
MOVF0,C
ANLC,/F0
JCDIV6
DIV6:
DJNZB,DIV5
四舍五入
ADDCA,R1;
将结果存回R3R4
ADDCA,R0
POPACC;
恢复R0R1R2
POPACC
计算商的阶码
LCALLMD;
阶码检验
规格化
(6)标号:
FCLR功能:
浮点数清零
操作数在[R0]中。
操作数被清零。
A堆栈需求:
2字节
FCLR:
MOV@R0,#41H
(7)标号:
FZER功能:
浮点数判零
若累加器A为零,则操作数[R0]为零,否则不为零。
FZER:
JNZZERO
ZERO:
RET
(8)标号:
FMOV功能:
浮点数传送
源操作数在[R1]中,目标地址为[R0]。
[R0]=[R1],[R1]不变。
FMOV:
(9)标号:
FPUS功能:
浮点数压栈
操作数压入栈顶。
A、R2、R3堆栈需求:
FPUS:
POPACC;
将返回地址保存在R2R3中
将操作数压入堆栈
将返回地址压入堆栈
RET;
返回主程序
(10)标号:
FPOP功能:
浮点数出栈
操作数处于栈顶。
操作数弹至[R0]中。
FPOP:
将操作数弹出堆栈,传送到[R0]中
(11)标号:
FCMP功能:
浮点数代数值比较(不影响待比较操作数)
待比较操作数分别在[R0]和[R1]中。
若CY=1,则[R0]<
[R1],若CY=0且A=0则[R0]=[R1],否则[R0]>
[R1]。
A、B、PSW堆栈需求:
FCMP:
数符比较
JNBACC.7,CMP2
两数异号,以[R0]数符为准
MOVA,#0FFH
CMP2:
两数同号,准备比较阶码
MOVC,ACC.6
保存[R0]的数符
比较阶码
SUBBA,B
JZCMP6
取阶码之差的符号
JNBF0,CMP5
CPLC;
[R0]为负时,结果取反
CMP5:
MOVA,#0FFH;
两数不相等
CMP6:
阶码相同时,准备比较尾数
SUBBA,@R1
MOVB,A;
保存部分差
ORLA,B;
生成是否相等信息
JZCMP7
JNBF0,CMP7
CMP7:
(12)标号:
FABS功能:
浮点绝对值函数
结果仍在[R0]中。
FABS:
读取操作数的阶码
清除数符
MOV@R0,A;
回传阶码
(13)标号:
FSGN功能:
浮点符号函数
累加器A=1时为正数,A=0FFH时为负数,A=0时为零。
PSW、A堆栈需求:
FSGN:
读尾数
JNZSGN
尾数为零,结束
SGN:
取数符
MOVA,#1;
按正数初始化
JNCSGN1;
是正数,结束
MOVA,#0FFH;
是负数,改变标志
SGN1:
R
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MCS51 浮点运算子程序库 浮点 运算子 程序库