1、MCS51 浮点运算子程序库 浮点运算子程序库2003-4-21 16:10:07阅读65次 浮点运算子程序库及其使用说明 本浮点子程序库有三个不同层次的版本,以便适应不同的应用场合:小型库(FQ51A.ASM):只包含浮点加、减、乘、除子程序。中型库(FQ51B.ASM):在小型库的基础上再增加绝对值、倒数、比较、平方、开平方、数制转换等子程序。大型库(FQ51.ASM):包含本说明书中的全部子程序。为便于读者使用本程序库,先将有关约定说明如下:双字节定点操作数:用R0或R1来表示存放在由R0或R1指示的连续单元中的数据,地址小的单元存放高字节。如果R0=1234H,若(R0)=30H,则(
2、30H)=12H,(31H)=34H。二进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为阶码(补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用双字节纯小数(原码)来表示。当尾数的最高位为时,便称为规格化浮点数,简称操作数。在程序说明中,也用R0或R1来表示R0或R1指示的浮点操作数,例如:当R0=-6.000时,则二进制浮点数表示为83C000H。若(R0)=30H,则(30H)=83H,(31H)=0C0H,(32H)=00H。十进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为阶码(二进制补码形式),第二字节为尾数的高字节,第三字节为
3、尾数的低字节,尾数用双字节码纯小数(原码)来表示。当十进制数的绝对值大于时,阶码就等于整数部分的位数,如 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、。运算精度:单次定点运算精度为结果最低位的当量值;单次二进制浮点算术运算的精度优于十万分之三;单次二进制浮点超越函数运算的精度优于万分之一;码浮点数本身的精度比较低(万分之一到千分之一),不宜作为运算的操作数,仅用于输入或输出时的数制转换。不管那种数据格式,随着连续运算的次数增加,精度都会下降。工作区:数据工作区固定在A、B、R2R7,数符或标志工作区固定在PSW和23H单元(位1CH1FH)。在浮点系统中,R2、R3、R4和位1FH为第一工作区,R5、R6、R7和位1EH为第二工作区。用户只要不在工作区中存放无关的或非消耗性的信息,程序就具有较好的透明性。子程序调用范例:由于本程序库特别注意
5、了各子程序接口的相容性,很容易采用积木方式(或流水线方式)完成一个公式的计算。以浮点运算为例:计算 = () 已知:a=-123.4;b=0.7577;c=56.34;d=1.276; 它们分别存放在30H、33H、36H、39H开始的连续三个单元中。用码浮点数表示时,分别为a=831234H;b=007577H;c=025634H;d=011276H。求解过程:通过调用子程序,将各变量转换成二进制浮点操作数,再进行各种运算,最后调用子程序,还原成十进制形式,供输出使用。程序如下:TEST: MOV R0,#39H ;指向码浮点操作数LCALL BTOF ;将其转换成二进制浮点操作数MOV R
6、0,#36H ;指向码浮点操作数LCALL BTOF ;将其转换成二进制浮点操作数MOV R0,#33H ;指向码浮点操作数LCALL BTOF ;将其转换成二进制浮点操作数MOV R0,#30H ;指向码浮点操作数LCALL BTOF ;将其转换成二进制浮点操作数MOV R1,#33H ;指向二进制浮点操作数LCALL FMUL ;进行浮点乘法运算MOV R1,#36H ;指向二进制浮点操作数LCALL FDIV ;进行浮点除法运算MOV R1,#39H ;指向二进制浮点操作数LCALL FADD ;进行浮点加法运算LCALL FSIN ;进行浮点正弦运算LCALL FABS ;进行浮点绝对
7、值运算LCALL FSQR ;进行浮点开平方运算LCALL FLN ;进行浮点对数运算LCALL FTOB ;将结果转换成码浮点数STOP: LJMP STOPEND运行结果,R0=804915H,即=-0.4915,比较精确的结果应该是-0.491437。() 标号: 功能:浮点数格式化入口条件:待格式化浮点操作数在R0中。出口信息:已格式化浮点操作数仍在R0中。影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 字节FSDT: LCALL MVR0 ;将待格式化操作数传送到第一工作区中LCALL RLN ;通过左规完成格式化LJMP MOV0 ;将已格式化浮点操作数传回到R0中(
8、) 标号: 功能:浮点数加法入口条件:被加数在R0中,加数在R1中。出口信息:OV=0时,和仍在R0中,OV=1时,溢出。影响资源:PSW、A、B、R2R7、位1EH、1FH 堆栈需求: 字节FADD: CLR F0 ;设立加法标志SJMP AS ;计算代数和() 标号: 功能:浮点数减法入口条件:被减数在R0中,减数在R1中。出口信息:OV=0时,差仍在R0中,OV=1时,溢出。影响资源:PSW、A、B、R2R7、位1EH、1FH 堆栈需求:字节FSUB: SETB F0 ;设立减法标志AS: LCALL MVR1 ;计算代数和。先将R1传送到第二工作区MOV C,F0 ;用加减标志来校正第
9、二操作数的有效符号RRC AXRL A,R1MOV C,ACC.7ASN: MOV 1EH,C ;将第二操作数的有效符号存入位1EH中XRL A,R0 ;与第一操作数的符号比较RLC AMOV F0,C ;保存比较结果LCALL MVR0 ;将R0传送到第一工作区中LCALL AS1 ;在工作寄存器中完成代数运算MOV0: INC R0 ;将结果传回到R0中的子程序入口INC R0MOV A,R4 ;传回尾数的低字节MOV R0,ADEC R0MOV A,R3 ;传回尾数的高字节MOV R0,ADEC R0MOV A,R2 ;取结果的阶码MOV C,1FH ;取结果的数符MOV ACC.7,C
10、 ;拼入阶码中MOV R0,ACLR ACC.7 ;不考虑数符CLR OV ;清除溢出标志CJNE A,#3FH,MV01;阶码是否上溢?SETB OV ;设立溢出标志MV01: MOV A,R0 ;取出带数符的阶码RETMVR0: MOV A,R0 ;将R0传送到第一工作区中的子程序MOV C,ACC.7 ;将数符保存在位1FH中MOV 1FH,CMOV C,ACC.6 ;将阶码扩充为补码MOV ACC.7,CMOV R2,A ;存放在R2中INC R0MOV A,R0 ;将尾数高字节存放在R3中MOV R3,AINC R0MOV A,R0 ;将尾数低字节存放在R4中MOV R4,ADEC
11、R0 ;恢复数据指针DEC R0RETMVR1: MOV A,R1 ;将R1传送到第二工作区中的子程序MOV C,ACC.7 ;将数符保存在位1EH中MOV 1EH,CMOV C,ACC.6 ;将阶码扩充为补码MOV ACC.7,CMOV R5,A ;存放在R5中INC R1MOV A,R1 ;将尾数高字节存放在R6中MOV R6,AINC R1MOV A,R1 ;将尾数低字节存放在R7中MOV R7,ADEC R1 ;恢复数据指针DEC R1RETAS1: MOV A,R6 ;读取第二操作数尾数高字节ORL A,R7JZ AS2 ;第二操作数为零,不必运算MOV A,R3 ;读取第一操作数尾
12、数高字节ORL A,R4JNZ EQ1MOV A,R6 ;第一操作数为零,结果以第二操作数为准MOV R3,AMOV A,R7MOV R4,AMOV A,R5MOV R2,AMOV C,1EHMOV 1FH,CAS2: RETEQ1: MOV A,R2 ;对阶,比较两个操作数的阶码XRL A,R5JZ AS4 ;阶码相同,对阶结束JB ACC.7,EQ3;阶符互异MOV A,R2 ;阶符相同,比较大小CLR CSUBB A,R5JC EQ4EQ2: CLR C ;第二操作数右规一次MOV A,R6 ;尾数缩小一半RRC AMOV R6,AMOV A,R7RRC AMOV R7,AINC R5
13、;阶码加一ORL A,R6 ;尾数为零否?JNZ EQ1 ;尾数不为零,继续对阶MOV A,R2 ;尾数为零,提前结束对阶MOV R5,ASJMP AS4EQ3: MOV A,R2 ;判断第一操作数阶符JNB ACC.7,EQ2;如为正,右规第二操作数EQ4: CLR CLCALL RR1 ;第一操作数右规一次ORL A,R3 ;尾数为零否?JNZ EQ1 ;不为零,继续对阶MOV A,R5 ;尾数为零,提前结束对阶MOV R2,AAS4: JB F0,AS5 ;尾数加减判断MOV A,R4 ;尾数相加ADD A,R7MOV R4,AMOV A,R3 ADDC A,R6MOV R3,AJNC
14、AS2LJMP RR1 ;有进位,右规一次AS5: CLR C ;比较绝对值大小MOV A,R4SUBB A,R7MOV B,AMOV A,R3SUBB A,R6JC AS6MOV R4,B ;第一尾数减第二尾数MOV R3,ALJMP RLN ;结果规格化AS6: CPL 1FH ;结果的符号与第一操作数相反CLR C ;结果的绝对值为第二尾数减第一尾数MOV A,R7SUBB A,R4MOV R4,AMOV A,R6SUBB A,R3MOV R3,ARLN: MOV A,R3 ;浮点数规格化ORL A,R4 ;尾数为零否?JNZ RLN1MOV R2,#0C1H;阶码取最小值RET RLN
15、1: MOV A,R3JB ACC.7,RLN2;尾数最高位为一否?CLR C ;不为一,左规一次LCALL RL1SJMP RLN ;继续判断RLN2: CLR OV ;规格化结束RETRL1: MOV A,R4 ;第一操作数左规一次RLC A ;尾数扩大一倍MOV R4,AMOV A,R3RLC AMOV R3,ADEC R2 ;阶码减一CJNE R2,#0C0H,RL1E;阶码下溢否?CLR AMOV R3,A ;阶码下溢,操作数以零计MOV R4,AMOV R2,#0C1HRL1E: CLR OVRETRR1: MOV A,R3 ;第一操作数右规一次RRC A ;尾数缩小一半MOV R
16、3,AMOV A,R4RRC AMOV R4,AINC R2 ;阶码加一CLR OV ;清溢出标志CJNE R2,#40H,RR1E;阶码上溢否?MOV R2,#3FH ;阶码溢出SETB OVRR1E: RET() 标号: 功能:浮点数乘法入口条件:被乘数在R0中,乘数在R1中。出口信息:OV=0时,积仍在R0中,OV=1时,溢出。影响资源:PSW、A、B、R2R7、位1EH、1FH 堆栈需求:字节FMUL: LCALL MVR0 ;将R0传送到第一工作区中MOV A,R0XRL A,R1 ;比较两个操作数的符号RLC AMOV 1FH,C ;保存积的符号LCALL MUL0 ;计算积的绝对
17、值LJMP MOV0 ;将结果传回到R0中MUL0: LCALL MVR1 ;将R1传送到第二工作区中MUL1: MOV A,R3 ;第一尾数为零否?ORL A,R4JZ MUL6MOV A,R6 ;第二尾数为零否?ORL A,R7JZ MUL5MOV A,R7 ;计算R3R4R6R7R3R4MOV B,R4MUL ABMOV A,BXCH A,R7MOV B,R3MUL ABADD A,R7MOV R7,ACLR AADDC A,BXCH A,R4MOV B,R6MUL ABADD A,R7MOV R7,AMOV A,BADDC A,R4MOV R4,ACLR ARLC AXCH A,R3M
18、OV B,R6MUL ABADD A,R4MOV R4,AMOV A,BADDC A,R3MOV R3,AJB ACC.7,MUL2;积为规格化数否?MOV A,R7 ;左规一次RLC AMOV R7,ALCALL RL1MUL2: MOV A,R7JNB ACC.7,MUL3INC R4MOV A,R4JNZ MUL3INC R3MOV A,R3JNZ MUL3MOV R3,#80HINC R2MUL3: MOV A,R2 ;求积的阶码ADD A,R5MD: MOV R2,A ;阶码溢出判断JB ACC.7,MUL4JNB ACC.6,MUL6MOV R2,#3FH ;阶码上溢,设立标志SE
19、TB OVRETMUL4: JB ACC.6,MUL6MUL5: CLR A ;结果清零(因子为零或阶码下溢)MOV R3,AMOV R4,AMOV R2,#41HMUL6: CLR OVRET() 标号: 功能:浮点数除法入口条件:被除数在R0中,除数在R1中。出口信息:OV=0时,商仍在R0中,OV=1时,溢出。影响资源:PSW、A、B、R2R7、位1EH、1FH 堆栈需求: 字节FDIV: INC R0MOV A,R0INC R0ORL A,R0DEC R0DEC R0JNZ DIV1MOV R0,#41H;被除数为零,不必运算CLR OVRETDIV1: INC R1MOV A,R1I
20、NC R1 ORL A,R1DEC R1DEC R1 JNZ DIV2 SETB OV ;除数为零,溢出RET DIV2: LCALL MVR0 ;将R0传送到第一工作区中MOV A,R0XRL A,R1 ;比较两个操作数的符号RLC AMOV 1FH,C ;保存结果的符号LCALL MVR1 ;将R1传送到第二工作区中LCALL DIV3 ;调用工作区浮点除法LJMP MOV0 ;回传结果DIV3: CLR C ;比较尾数的大小MOV A,R4SUBB A,R7MOV A,R3SUBB A,R6JC DIV4LCALL RR1 ;被除数右规一次SJMP DIV3DIV4: CLR A ;借用
21、R0R1R2作工作寄存器XCH A,R0 ;清零并保护之PUSH ACCCLR AXCH A,R1PUSH ACCMOV A,R2PUSH ACCMOV B,#10H ;除法运算,R3R4R6R7R0R1DIV5: CLR CMOV A,R1RLC AMOV R1,AMOV A,R0RLC AMOV R0,AMOV A,R4RLC AMOV R4,AXCH A,R3RLC AXCH A,R3MOV F0,CCLR CSUBB A,R7MOV R2,AMOV A,R3SUBB A,R6ANL C,/F0JC DIV6MOV R3,AMOV A,R2MOV R4,AINC R1DIV6: DJNZ
22、 B,DIV5MOV A,R6 ;四舍五入CLR CRRC ASUBB A,R3CLR AADDC A,R1 ;将结果存回R3R4MOV R4,ACLR AADDC A,R0MOV R3,APOP ACC ;恢复R0R1R2MOV R2,APOP ACCMOV R1,APOP ACCMOV R0,AMOV A,R2 ;计算商的阶码CLR CSUBB A,R5LCALL MD ;阶码检验LJMP RLN ;规格化() 标号: 功能:浮点数清零入口条件:操作数在R0中。出口信息:操作数被清零。影响资源:A 堆栈需求: 字节FCLR: INC R0INC R0CLR AMOV R0,ADEC R0M
23、OV R0,ADEC R0MOV R0,#41HRET () 标号: 功能:浮点数判零入口条件:操作数在R0中。出口信息:若累加器A为零,则操作数R0为零,否则不为零。影响资源:A 堆栈需求: 字节FZER: INC R0INC R0MOV A,R0DEC R0ORL A,R0DEC R0JNZ ZEROMOV R0,#41HZERO: RET () 标号: 功能:浮点数传送入口条件:源操作数在R1中,目标地址为R0。出口信息:R0=R1,R1不变。影响资源:A 堆栈需求: 字节FMOV: INC R0INC R0INC R1INC R1MOV A,R1MOV R0,ADEC R0DEC R1
24、MOV A,R1MOV R0,ADEC R0DEC R1MOV A,R1MOV R0,ARET() 标号: 功能:浮点数压栈入口条件:操作数在R0中。出口信息:操作数压入栈顶。影响资源:A、R2、R3 堆栈需求: 字节FPUS: POP ACC ;将返回地址保存在R2R3中MOV R2,APOP ACCMOV R3,AMOV A,R0 ;将操作数压入堆栈PUSH ACCINC R0MOV A,R0PUSH ACCINC R0MOV A,R0PUSH ACCDEC R0DEC R0MOV A,R3 ;将返回地址压入堆栈PUSH ACCMOV A,R2PUSH ACCRET ;返回主程序() 标号
25、: 功能:浮点数出栈入口条件:操作数处于栈顶。出口信息:操作数弹至R0中。影响资源:A、R2、R3 堆栈需求: 字节FPOP: POP ACC ;将返回地址保存在R2R3中MOV R2,APOP ACCMOV R3,AINC R0INC R0POP ACC ;将操作数弹出堆栈,传送到R0中MOV R0,ADEC R0POP ACCMOV R0,ADEC R0POP ACCMOV R0,AMOV A,R3 ;将返回地址压入堆栈PUSH ACCMOV A,R2PUSH ACCRET ;返回主程序() 标号: 功能:浮点数代数值比较(不影响待比较操作数)入口条件:待比较操作数分别在R0和R1中。出口
26、信息:若CY=1,则R0 R1。影响资源:A、B、PSW 堆栈需求: 字节FCMP: MOV A,R0 ;数符比较XRL A,R1JNB ACC.7,CMP2MOV A,R0 ;两数异号,以R0数符为准RLC AMOV A,#0FFHRET CMP2: MOV A,R1 ;两数同号,准备比较阶码MOV C,ACC.6MOV ACC.7,CMOV B,AMOV A,R0MOV C,ACC.7MOV F0,C ;保存R0的数符MOV C,ACC.6MOV ACC.7,CCLR C ;比较阶码SUBB A,BJZ CMP6RLC A ;取阶码之差的符号JNB F0,CMP5CPL C ;R0为负时,
27、结果取反CMP5: MOV A,#0FFH ;两数不相等RET CMP6: INC R0 ;阶码相同时,准备比较尾数INC R0INC R1INC R1CLR CMOV A,R0SUBB A,R1MOV B,A ;保存部分差 DEC R0DEC R1MOV A,R0SUBB A,R1DEC R0DEC R1ORL A,B ;生成是否相等信息JZ CMP7JNB F0,CMP7CPL C ;R0为负时,结果取反CMP7: RET() 标号: 功能:浮点绝对值函数入口条件:操作数在R0中。出口信息:结果仍在R0中。影响资源:A 堆栈需求: 字节FABS: MOV A,R0 ;读取操作数的阶码CLR ACC.7 ;清除数符MOV R0,A ;回传阶码RET() 标号: 功能:浮点符号函数入口条件:操作数在R0中。出口信息:累加器 A=1 时为正数,A=0FFH时为负数,A=0 时为零。影响资源:PSW、A 堆栈需求: 字节FSGN: INC R0 ;读尾数MOV A,R0INC R0ORL A,R0DEC R0DEC R0JNZ SGNRET ;尾数为零,结束SGN: MOV A,R0 ;读取操作数的阶码RLC A ;取数符MOV A,#1 ;按正数初始化JNC SGN1 ;是正数,结束MOV A,#0FFH ;是负数,改变标志SGN1: R
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1