MCS51 浮点运算子程序库.docx

上传人:b****4 文档编号:3732832 上传时间:2022-11-25 格式:DOCX 页数:43 大小:29.09KB
下载 相关 举报
MCS51 浮点运算子程序库.docx_第1页
第1页 / 共43页
MCS51 浮点运算子程序库.docx_第2页
第2页 / 共43页
MCS51 浮点运算子程序库.docx_第3页
第3页 / 共43页
MCS51 浮点运算子程序库.docx_第4页
第4页 / 共43页
MCS51 浮点运算子程序库.docx_第5页
第5页 / 共43页
点击查看更多>>
下载资源
资源描述

MCS51 浮点运算子程序库.docx

《MCS51 浮点运算子程序库.docx》由会员分享,可在线阅读,更多相关《MCS51 浮点运算子程序库.docx(43页珍藏版)》请在冰豆网上搜索。

MCS51 浮点运算子程序库.docx

MCS51浮点运算子程序库

MCS-51浮点运算子程序库

2003-4-2116:

10:

07      阅读65次

 

 

 

MCS-51浮点运算子程序库及其使用说明

本浮点子程序库有三个不同层次的版本,以便适应不同的应用场合:

1.小型库(FQ51A.ASM):

只包含浮点加、减、乘、除子程序。

2.中型库(FQ51B.ASM):

在小型库的基础上再增加绝对值、倒数、比较、平方、开平方、

数制转换等子程序。

3.大型库(FQ51.ASM):

包含本说明书中的全部子程序。

为便于读者使用本程序库,先将有关约定说明如下:

1.双字节定点操作数:

用[R0]或[R1]来表示存放在由R0或R1指示的连续单元中的数

据,地址小的单元存放高字节。

如果[R0]=1234H,若(R0)=30H,则(30H)=12H,(31H)=34H。

2.二进制浮点操作数:

用三个字节表示,第一个字节的最高位为数符,其余七位为

阶码(补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用双字节

纯小数(原码)来表示。

当尾数的最高位为1时,便称为规格化浮点数,简称操作数。

程序说明中,也用[R0]或[R1]来表示R0或R1指示的浮点操作数,例如:

当[R0]=-6.000时,

则二进制浮点数表示为83C000H。

若(R0)=30H,则(30H)=83H,(31H)=0C0H,(32H)=00H。

3.十进制浮点操作数:

用三个字节表示,第一个字节的最高位为数符,其余七位为

阶码(二进制补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用

双字节BCD码纯小数(原码)来表示。

当十进制数的绝对值大于1时,阶码就等于整数

部分的位数,如876.5的阶码是03H,-876.5的阶码是83H;当十进制数的绝对值小于1

时,阶码就等于80H减去小数点后面零的个数,例如0.00382的阶码是7EH,-0.00382

的阶码是0FEH。

在程序说明中,用[R0]或[R1]来表示R0或R1指示的十进制浮点操作数。

如有一个十进制浮点操作数存放在30H、31H、32H中,数值是-0.07315,即-0.7315乘以10

的-1次方,则(30H)=0FFH,31H=73H,(32H)=15H。

若用[R0]来指向它,则应使(R0)=30H。

4.运算精度:

单次定点运算精度为结果最低位的当量值;单次二进制浮点算术运算

的精度优于十万分之三;单次二进制浮点超越函数运算的精度优于万分之一;BCD码浮

点数本身的精度比较低(万分之一到千分之一),不宜作为运算的操作数,仅用于输入或

输出时的数制转换。

不管那种数据格式,随着连续运算的次数增加,精度都会下降。

5.工作区:

数据工作区固定在A、B、R2~R7,数符或标志工作区固定在PSW和23H单

元(位1CH~1FH)。

在浮点系统中,R2、R3、R4和位1FH为第一工作区,R5、R6、R7和位1EH

为第二工作区。

用户只要不在工作区中存放无关的或非消耗性的信息,程序就具有较好的

透明性。

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

LCALLBTOF;将其转换成二进制浮点操作数

MOVR0,#33H;指向BCD码浮点操作数b

LCALLBTOF;将其转换成二进制浮点操作数

MOVR0,#30H;指向BCD码浮点操作数a

LCALLBTOF;将其转换成二进制浮点操作数

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堆栈需求:

6字节

FADD:

CLRF0;设立加法标志

SJMPAS;计算代数和

(3)标号:

FSUB功能:

浮点数减法

入口条件:

被减数在[R0]中,减数在[R1]中。

出口信息:

OV=0时,差仍在[R0]中,OV=1时,溢出。

影响资源:

PSW、A、B、R2~R7、位1EH、1FH堆栈需求:

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;传回尾数的高字节

MOV@R0,A

DECR0

MOVA,R2;取结果的阶码

MOVC,1FH;取结果的数符

MOVACC.7,C;拼入阶码中

MOV@R0,A

CLRACC.7;不考虑数符

CLROV;清除溢出标志

CJNEA,#3FH,MV01;阶码是否上溢?

SETBOV;设立溢出标志

MV01:

MOVA,@R0;取出带数符的阶码

RET

MVR0:

MOVA,@R0;将[R0]传送到第一工作区中的子程序

MOVC,ACC.7;将数符保存在位1FH中

MOV1FH,C

MOVC,ACC.6;将阶码扩充为8bit补码

MOVACC.7,C

MOVR2,A;存放在R2中

INCR0

MOVA,@R0;将尾数高字节存放在R3中

MOVR3,A

INCR0

MOVA,@R0;将尾数低字节存放在R4中

MOVR4,A

DECR0;恢复数据指针

DECR0

RET

MVR1:

MOVA,@R1;将[R1]传送到第二工作区中的子程序

MOVC,ACC.7;将数符保存在位1EH中

MOV1EH,C

MOVC,ACC.6;将阶码扩充为8bit补码

MOVACC.7,C

MOVR5,A;存放在R5中

INCR1

MOVA,@R1;将尾数高字节存放在R6中

MOVR6,A

INCR1

MOVA,@R1;将尾数低字节存放在R7中

MOVR7,A

DECR1;恢复数据指针

DECR1

RET

AS1:

MOVA,R6;读取第二操作数尾数高字节

ORLA,R7

JZAS2;第二操作数为零,不必运算

MOVA,R3;读取第一操作数尾数高字节

ORLA,R4

JNZEQ1

MOVA,R6;第一操作数为零,结果以第二操作数为准

MOVR3,A

MOVA,R7

MOVR4,A

MOVA,R5

MOVR2,A

MOVC,1EH

MOV1FH,C

AS2:

RET

EQ1:

MOVA,R2;对阶,比较两个操作数的阶码

XRLA,R5

JZAS4;阶码相同,对阶结束

JBACC.7,EQ3;阶符互异

MOVA,R2;阶符相同,比较大小

CLRC

SUBBA,R5

JCEQ4

EQ2:

CLRC;第二操作数右规一次

MOVA,R6;尾数缩小一半

RRCA

MOVR6,A

MOVA,R7

RRCA

MOVR7,A

INCR5;阶码加一

ORLA,R6;尾数为零否?

JNZEQ1;尾数不为零,继续对阶

MOVA,R2;尾数为零,提前结束对阶

MOVR5,A

SJMPAS4

EQ3:

MOVA,R2;判断第一操作数阶符

JNBACC.7,EQ2;如为正,右规第二操作数

EQ4:

CLRC

LCALLRR1;第一操作数右规一次

ORLA,R3;尾数为零否?

JNZEQ1;不为零,继续对阶

MOVA,R5;尾数为零,提前结束对阶

MOVR2,A

AS4:

JBF0,AS5;尾数加减判断

MOVA,R4;尾数相加

ADDA,R7

MOVR4,A

MOVA,R3

ADDCA,R6

MOVR3,A

JNCAS2

LJMPRR1;有进位,右规一次

AS5:

CLRC;比较绝对值大小

MOVA,R4

SUBBA,R7

MOVB,A

MOVA,R3

SUBBA,R6

JCAS6

MOVR4,B;第一尾数减第二尾数

MOVR3,A

LJMPRLN;结果规格化

AS6:

CPL1FH;结果的符号与第一操作数相反

CLRC;结果的绝对值为第二尾数减第一尾数

MOVA,R7

SUBBA,R4

MOVR4,A

MOVA,R6

SUBBA,R3

MOVR3,A

RLN:

MOVA,R3;浮点数规格化

ORLA,R4;尾数为零否?

JNZRLN1

MOVR2,#0C1H;阶码取最小值

RET

RLN1:

MOVA,R3

JBACC.7,RLN2;尾数最高位为一否?

CLRC;不为一,左规一次

LCALLRL1

SJMPRLN;继续判断

RLN2:

CLROV;规格化结束

RET

RL1:

MOVA,R4;第一操作数左规一次

RLCA;尾数扩大一倍

MOVR4,A

MOVA,R3

RLCA

MOVR3,A

DECR2;阶码减一

CJNER2,#0C0H,RL1E;阶码下溢否?

CLRA

MOVR3,A;阶码下溢,操作数以零计

MOVR4,A

MOVR2,#0C1H

RL1E:

CLROV

RET

RR1:

MOVA,R3;第一操作数右规一次

RRCA;尾数缩小一半

MOVR3,A

MOVA,R4

RRCA

MOVR4,A

INCR2;阶码加一

CLROV;清溢出标志

CJNER2,#40H,RR1E;阶码上溢否?

MOVR2,#3FH;阶码溢出

SETBOV

RR1E:

RET

 

(4)标号:

FMUL功能:

浮点数乘法

入口条件:

被乘数在[R0]中,乘数在[R1]中。

出口信息:

OV=0时,积仍在[R0]中,OV=1时,溢出。

影响资源:

PSW、A、B、R2~R7、位1EH、1FH堆栈需求:

6字节

FMUL:

LCALLMVR0;将[R0]传送到第一工作区中

MOVA,@R0

XRLA,@R1;比较两个操作数的符号

RLCA

MOV1FH,C;保存积的符号

LCALLMUL0;计算积的绝对值

LJMPMOV0;将结果传回到[R0]中

MUL0:

LCALLMVR1;将[R1]传送到第二工作区中

MUL1:

MOVA,R3;第一尾数为零否?

ORLA,R4

JZMUL6

MOVA,R6;第二尾数为零否?

ORLA,R7

JZMUL5

MOVA,R7;计算R3R4×R6R7-→R3R4

MOVB,R4

MULAB

MOVA,B

XCHA,R7

MOVB,R3

MULAB

ADDA,R7

MOVR7,A

CLRA

ADDCA,B

XCHA,R4

MOVB,R6

MULAB

ADDA,R7

MOVR7,A

MOVA,B

ADDCA,R4

MOVR4,A

CLRA

RLCA

XCHA,R3

MOVB,R6

MULAB

ADDA,R4

MOVR4,A

MOVA,B

ADDCA,R3

MOVR3,A

JBACC.7,MUL2;积为规格化数否?

MOVA,R7;左规一次

RLCA

MOVR7,A

LCALLRL1

MUL2:

MOVA,R7

JNBACC.7,MUL3

INCR4

MOVA,R4

JNZMUL3

INCR3

MOVA,R3

JNZMUL3

MOVR3,#80H

INCR2

MUL3:

MOVA,R2;求积的阶码

ADDA,R5

MD:

MOVR2,A;阶码溢出判断

JBACC.7,MUL4

JNBACC.6,MUL6

MOVR2,#3FH;阶码上溢,设立标志

SETBOV

RET

MUL4:

JBACC.6,MUL6

MUL5:

CLRA;结果清零(因子为零或阶码下溢)

MOVR3,A

MOVR4,A

MOVR2,#41H

MUL6:

CLROV

RET

 

(5)标号:

FDIV功能:

浮点数除法

入口条件:

被除数在[R0]中,除数在[R1]中。

出口信息:

OV=0时,商仍在[R0]中,OV=1时,溢出。

影响资源:

PSW、A、B、R2~R7、位1EH、1FH堆栈需求:

5字节

FDIV:

INCR0

MOVA,@R0

INCR0

ORLA,@R0

DECR0

DECR0

JNZDIV1

MOV@R0,#41H;被除数为零,不必运算

CLROV

RET

DIV1:

INCR1

MOVA,@R1

INCR1

ORLA,@R1

DECR1

DECR1

JNZDIV2

SETBOV;除数为零,溢出

RET

DIV2:

LCALLMVR0;将[R0]传送到第一工作区中

MOVA,@R0

XRLA,@R1;比较两个操作数的符号

RLCA

MOV1FH,C;保存结果的符号

LCALLMVR1;将[R1]传送到第二工作区中

LCALLDIV3;调用工作区浮点除法

LJMPMOV0;回传结果

DIV3:

CLRC;比较尾数的大小

MOVA,R4

SUBBA,R7

MOVA,R3

SUBBA,R6

JCDIV4

LCALLRR1;被除数右规一次

SJMPDIV3

DIV4:

CLRA;借用R0R1R2作工作寄存器

XCHA,R0;清零并保护之

PUSHACC

CLRA

XCHA,R1

PUSHACC

MOVA,R2

PUSHACC

MOVB,#10H;除法运算,R3R4/R6R7-→R0R1

DIV5:

CLRC

MOVA,R1

RLCA

MOVR1,A

MOVA,R0

RLCA

MOVR0,A

MOVA,R4

RLCA

MOVR4,A

XCHA,R3

RLCA

XCHA,R3

MOVF0,C

CLRC

SUBBA,R7

MOVR2,A

MOVA,R3

SUBBA,R6

ANLC,/F0

JCDIV6

MOVR3,A

MOVA,R2

MOVR4,A

INCR1

DIV6:

DJNZB,DIV5

MOVA,R6;四舍五入

CLRC

RRCA

SUBBA,R3

CLRA

ADDCA,R1;将结果存回R3R4

MOVR4,A

CLRA

ADDCA,R0

MOVR3,A

POPACC;恢复R0R1R2

MOVR2,A

POPACC

MOVR1,A

POPACC

MOVR0,A

MOVA,R2;计算商的阶码

CLRC

SUBBA,R5

LCALLMD;阶码检验

LJMPRLN;规格化

(6)标号:

FCLR功能:

浮点数清零

入口条件:

操作数在[R0]中。

出口信息:

操作数被清零。

影响资源:

A堆栈需求:

2字节

FCLR:

INCR0

INCR0

CLRA

MOV@R0,A

DECR0

MOV@R0,A

DECR0

MOV@R0,#41H

RET

 

(7)标号:

FZER功能:

浮点数判零

入口条件:

操作数在[R0]中。

出口信息:

若累加器A为零,则操作数[R0]为零,否则不为零。

影响资源:

A堆栈需求:

2字节

FZER:

INCR0

INCR0

MOVA,@R0

DECR0

ORLA,@R0

DECR0

JNZZERO

MOV@R0,#41H

ZERO:

RET

(8)标号:

FMOV功能:

浮点数传送

入口条件:

源操作数在[R1]中,目标地址为[R0]。

出口信息:

[R0]=[R1],[R1]不变。

影响资源:

A堆栈需求:

2字节

FMOV:

INCR0

INCR0

INCR1

INCR1

MOVA,@R1

MOV@R0,A

DECR0

DECR1

MOVA,@R1

MOV@R0,A

DECR0

DECR1

MOVA,@R1

MOV@R0,A

RET

 

(9)标号:

FPUS功能:

浮点数压栈

入口条件:

操作数在[R0]中。

出口信息:

操作数压入栈顶。

影响资源:

A、R2、R3堆栈需求:

5字节

FPUS:

POPACC;将返回地址保存在R2R3中

MOVR2,A

POPACC

MOVR3,A

MOVA,@R0;将操作数压入堆栈

PUSHACC

INCR0

MOVA,@R0

PUSHACC

INCR0

MOVA,@R0

PUSHACC

DECR0

DECR0

MOVA,R3;将返回地址压入堆栈

PUSHACC

MOVA,R2

PUSHACC

RET;返回主程序

(10)标号:

FPOP功能:

浮点数出栈

入口条件:

操作数处于栈顶。

出口信息:

操作数弹至[R0]中。

影响资源:

A、R2、R3堆栈需求:

2字节

FPOP:

POPACC;将返回地址保存在R2R3中

MOVR2,A

POPACC

MOVR3,A

INCR0

INCR0

POPACC;将操作数弹出堆栈,传送到[R0]中

MOV@R0,A

DECR0

POPACC

MOV@R0,A

DECR0

POPACC

MOV@R0,A

MOVA,R3;将返回地址压入堆栈

PUSHACC

MOVA,R2

PUSHACC

RET;返回主程序

(11)标号:

FCMP功能:

浮点数代数值比较(不影响待比较操作数)

入口条件:

待比较操作数分别在[R0]和[R1]中。

出口信息:

若CY=1,则[R0]<[R1],若CY=0且A=0则[R0]=[R1],否则[R0]>[R1]。

影响资源:

A、B、PSW堆栈需求:

2字节

FCMP:

MOVA,@R0;数符比较

XRLA,@R1

JNBACC.7,CMP2

MOVA,@R0;两数异号,以[R0]数符为准

RLCA

MOVA,#0FFH

RET

CMP2:

MOVA,@R1;两数同号,准备比较阶码

MOVC,ACC.6

MOVACC.7,C

MOVB,A

MOVA,@R0

MOVC,ACC.7

MOVF0,C;保存[R0]的数符

MOVC,ACC.6

MOVACC.7,C

CLRC;比较阶码

SUBBA,B

JZCMP6

RLCA;取阶码之差的符号

JNBF0,CMP5

CPLC;[R0]为负时,结果取反

CMP5:

MOVA,#0FFH;两数不相等

RET

CMP6:

INCR0;阶码相同时,准备比较尾数

INCR0

INCR1

INCR1

CLRC

MOVA,@R0

SUBBA,@R1

MOVB,A;保存部分差

DECR0

DECR1

MOVA,@R0

SUBBA,@R1

DECR0

DECR1

ORLA,B;生成是否相等信息

JZCMP7

JNBF0,CMP7

CPLC;[R0]为负时,结果取反

CMP7:

RET

 

(12)标号:

FABS功能:

浮点绝对值函数

入口条件:

操作数在[R0]中。

出口信息:

结果仍在[R0]中。

影响资源:

A堆栈需求:

2字节

FABS:

MOVA,@R0;读取操作数的阶码

CLRACC.7;清除数符

MOV@R0,A;回传阶码

RET

(13)标号:

FSGN功能:

浮点符号函数

入口条件:

操作数在[R0]中。

出口信息:

累加器A=1时为正数,A=0FFH时为负数,A=0时为零。

影响资源:

PSW、A堆栈需求:

2字节

FSGN:

INCR0;读尾数

MOVA,@R0

INCR0

ORLA,@R0

DECR0

DECR0

JNZSGN

RET;尾数为零,结束

SGN:

MOVA,@R0;读取操作数的阶码

RLCA;取数符

MOVA,#1;按正数初始化

JNCSGN1;是正数,结束

MOVA,#0FFH;是负数,改变标志

SGN1:

R

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1