欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

浮点运算简介(part I)... (6千字)

浮点运算简介(part I)... (6千字)

浮点运算简介
                                        Hume/冷雨飘心

对于习惯于C的灵活多变的数据类型和方便的计算那些人而言,了解底层的浮点运算似乎没有什么意义,现在Visual盛行的时代还有多少人关心那些所谓的底层呢?
对了AfOs来说,浮点运算是编程中很重要的一部分,因为我们可能会面临一些稍微复杂的运算,如果你和我一样是Die-hard的asm拥护者,不想轻易用C来解决问题,你肯定能想像在asm下用整数运算求sin(2.3)的痛苦,实际上,微机早就为我们准备了解决之道:那就是浮点运算.但现在关于浮点运算的资料较少,相信很多人和我一样还不掌握这种强有力的技术,那好,我们一起来学习学习.
                     

                                (一)浮点数
                                    (This Part mainly Froe Bill's Article)
在这之前,先来看几个术语:
FPU->Floating Point Unit,浮点运算部件
BCD->Binary Coded Decimal 压缩的二十进制数,是用4个位来表示数字0~9,一个byte表示两个十进制数,比如01111001表示89
科学计数法:这是科学的~~~~具体含义查查初中还是小学的数学课本 D:)
浮点运算使用三种不同的数据:
        1)整数(Integer),又分为字,短整数(Short Integer)和长整数(Long Integer)
        2)实数(Real)分单精度(Single Real)和双精度(Double Real)
        3)压缩的二十进制数(BCD)
   
    下面是其位数(bits)和能表示的大致范围和

        Type            Length          Range
        -----------------------------------------------
        Word Integer    16 bit          -32768 to 32768
        Short Integer  32 bit          -2.14e9 to 2.14e9
        Long Integer    64 bit          -9.22e18 to 9.22e18
        Single Real    32 bit          1.18e-38 to 3.40e38
        Double Real    64 bit          2.23e-308 to 1.79e308
        extended Real  80 bit          3.37e-1932 to 1.18e4932
        Packed BCD      80 bit          -1e18 to 1e18
双精度数和扩展精度数表示范围对一般应用来说已经足够大了!
1)整数,以补码形式存储,正数的补码是其本身,负数补码是其绝对值的各位变反后加1,下面是实际存储的例子:
        0024            var1 dw 24
        FFFE            var2 dw -2
        000004D2        var3 dd 1234
        FFFFFF85        var4 dd -123
        0000000000002694var5 dq 9876
        FFFFFFFFFFFFFEBFvar6 dq -321
2)BCD数
        在FPU中用80位表示正好是浮点堆寄存器的宽度,在其格式如下存储:
    Bit
        79___72_71________________________________________0
        符号            ---18个二十进制数--------
看下面的例子:
        00000000000000012345        var1  dt    12345
        80000000000000000100        var2  dt    -100
3)浮点数,这个复杂点,有三种格式
        单精度:_31_30________23_22___________0
              符号    指数        有效数
        双精度:_63_62__________52_51__________________0
              符号    指数            有效数
        扩展精度数:
              _79_78____________64_63___________________0
              符号    指数              有效数
例子:
        C377999A                    var1  dd      -247.6
        40000000                    var2  dd      2.0
        486F4200                    var3  real4  2.45e+5
        4059100000000000            var4  dq      100.25
        3F543BF727136A40            var5  real8  0.00123
        C377999A                    var1  dd      -247.6
        40000000                    var2  dd      2.0
        486F4200                    var3  real4  2.45e+5
        4059100000000000            var4  dq      100.25
        3F543BF727136A40            var5  real8  0.001235
        400487F34D6A161E4F76        var6  real10  33.9876
DD和real4都可以在asm中来定义单精度浮点数,4 bytes
DQ和real8都可以在asm中来定义双精度浮点数,8 bytes
DT和real10都可以在asm中来定义扩展精度浮点数,10 bytes
                       
                        (二)浮点部件
FPU从功能上分为两个部分:控制单元和运算单元,控制单元主要面向CPU,而算数单元负责具体算数运算.
FPU即浮点部件包括8个通用寄存器,5个错误指针寄存器和三个控制寄存器.
1)8个通用寄存器每个80 bit,形成一个寄存器堆栈,所有的计算结果都保存在寄存器堆栈中,其中数据全部是80位的扩展精度格式,即使是BCD,整数,单精度和双精度等在装入寄存器的时候都要被FPU自动转化为80位的扩展精度格式,注意栈顶通常表示为ST(0),然后是ST(1)...ST(i),ST(i)是相对于栈顶而言的.
和堆栈很相似,只不过宽度为80bit,映像如下:
                _______________________
              |        ST(0)          |     
              |_______________________|
              |        ST(1)          |
              |_______________________|
              |    ......            |
              |    ......            |
              |        ST(i)          |           
              |_______________________|
2)控制寄存器,FPU有三个控制寄存器:状态寄存器,控制寄存器和标记寄存器
状态寄存器->SW
        _M_____D________10___9____8___7_________5_________________________0__
      |  B |  C3| TOP| C2 | C1 | C0 | ES |    | PE | UE | OE | ZE | DE | IE |
      |____|____|____|____|____|____|____|____|____|____|____|____|____|____|
B:    浮点部件正忙
C0-C3  指示浮点运算的结果,不同指令有不同含义
TOP    指示栈顶,通常是0
ES 以下任何位置位 (pe, ue, oe, ze, de, or ie) 则置位
PE 精度故障 
UE 数字太小无法表示溢出 
OE 现有精度无法表示,数字太大溢出 
ZE 除0错 
DE 指示至少有一个操作数未规格化 
IE 无效错误,指示堆栈上溢或下溢,无效操作数等

控制寄存器:
        _15____________10___9____8___7_________5______________________0__
      |              |IC | RC | PC  |    | PM | UM | OM | ZM | DM | IM |
      |____|____|____|___|__|_|__|__|____|____|____|____|____|____|____|
IC 无穷大控制,对486,已经无效
RC 舍入控制
        00 = 朝最接近或者偶数舍入
        01 = 朝负无穷大方向舍入
        10 = 朝
正无穷大方向舍入
        11 = 超0方向截断
PC 精度控制
        00 = 单精度
        01 = 保留
        10 = 双精度
        11 = 扩展精度
PM~IM 屏蔽状态寄存器低5位指示的错误.为1则屏蔽.

标记寄存器:
        每2 bit表示一个对应堆栈寄存器的状态,具体含义如下:
      15________________________________________3_____0
      |Tag7 |...................................|tag1|
      |_____|___________________________________|____|
       
含义:
        00 = 有效
        01 = 零
        10 = 无效或无穷大
        11 = 为空
                             

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功