📄 浮点运算简介.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0048)http://www.pediy.com/bbshtml/BBS5/pediy50039.htm -->
<HTML><HEAD><TITLE>浮点运算简介</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312"><LINK
href="浮点运算简介.files/css.css" type=text/css rel=stylesheet>
<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY text=#000000 bgColor=#ffffff background=浮点运算简介.files/back.gif>
<P class=pediy><FONT color=blue>标 题:</FONT>浮点运算简介(part I)... (6千字)<BR><FONT
color=blue>发信人<SPAN class=pediy>:</SPAN></FONT><SPAN class=pediy>hume<BR><FONT
color=blue>时 间:</FONT>2002-3-31 8:48:40<BR><FONT
color=blue>详细信息:</FONT><BR></SPAN></P>
<BLOCKQUOTE><SPAN class=pediy>浮点运算简介 <BR><BR>
Hume/冷雨飘心 <BR><SPAN
class=pediy><BR>对于习惯于C的灵活多变的数据类型和方便的计算那些人而言,了解底层的浮点运算似乎没有什么意义,现在Visual盛行的时代还有多少人关心那些所谓的底层呢?
<BR>对了AfOs来说,浮点运算是编程中很重要的一部分,因为我们可能会面临一些稍微复杂的运算,如果你和我一样是Die-hard的asm拥护者,不想轻易用C来解决问题,你肯定能想像在asm下用整数运算求sin(2.3)的痛苦,实际上,微机早就为我们准备了解决之道:那就是浮点运算.但现在关于浮点运算的资料较少,相信很多人和我一样还不掌握这种强有力的技术,那好,我们一起来学习学习.
<BR>
<BR><BR><BR>
(一)浮点数 <BR>
(This Part mainly Froe Bill's
Article) <BR>在这之前,先来看几个术语: <BR>FPU->Floating Point Unit,浮点运算部件
<BR>BCD->Binary Coded Decimal
压缩的二十进制数,是用4个位来表示数字0~9,一个byte表示两个十进制数,比如01111001表示89
<BR>科学计数法:这是科学的~~~~具体含义查查初中还是小学的数学课本 D:) <BR><BR>浮点运算使用三种不同的数据: <BR>
1)整数(Integer),又分为字,短整数(Short Integer)和长整数(Long Integer)
<BR> 2)实数(Real)分单精度(Single Real)和双精度(Double Real)
<BR> 3)压缩的二十进制数(BCD) <BR> <BR>
下面是其位数(bits)和能表示的大致范围和 <BR><BR><BR>
Type Length
Range <BR>
----------------------------------------------- <BR>
Word Integer 16 bit
-32768 to 32768 <BR> Short Integer 32
bit -2.14e9 to 2.14e9 <BR>
Long Integer 64 bit
-9.22e18 to 9.22e18 <BR> Single Real
32 bit 1.18e-38 to 3.40e38 <BR>
Double Real 64 bit
2.23e-308 to 1.79e308 <BR> extended
Real 80 bit 3.37e-1932 to 1.18e4932
<BR> Packed BCD 80 bit
-1e18 to 1e18 <BR><BR>双精度数和扩展精度数表示范围对一般应用来说已经足够大了!
<BR><BR>1)整数,以补码形式存储,正数的补码是其本身,负数补码是其绝对值的各位变反后加1,下面是实际存储的例子: <BR>
0024 var1 dw 24
<BR> FFFE
var2 dw -2 <BR> 000004D2
var3 dd 1234 <BR> FFFFFF85
var4 dd -123 <BR> 0000000000002694var5 dq
9876 <BR> FFFFFFFFFFFFFEBFvar6 dq -321
<BR><BR>2)BCD数 <BR>
在FPU中用80位表示正好是浮点堆寄存器的宽度,在其格式如下存储: <BR> Bit <BR>
79___72_71________________________________________0 <BR>
符号
---18个二十进制数-------- <BR>看下面的例子: <BR>
00000000000000012345 var1 dt
12345 <BR> 80000000000000000100
var2 dt -100 <BR><BR>3)浮点数,这个复杂点,有三种格式
<BR><BR> 单精度:_31_30________23_22___________0
<BR> 符号 指数
有效数 <BR><BR>
双精度:_63_62__________52_51__________________0 <BR>
符号 指数
有效数 <BR><BR> 扩展精度数: <BR>
_79_78____________64_63___________________0
<BR> 符号 指数
有效数 <BR>例子: <BR>
C377999A
var1 dd -247.6 <BR>
40000000
var2 dd 2.0 <BR>
486F4200
var3 real4 2.45e+5 <BR>
4059100000000000 var4 dq
100.25 <BR> 3F543BF727136A40
var5 real8 0.00123
<BR><BR> C377999A
var1 dd -247.6
<BR> 40000000
var2 dd 2.0
<BR> 486F4200
var3 real4 2.45e+5 <BR>
4059100000000000
var4 dq 100.25 <BR>
3F543BF727136A40 var5
real8 0.001235 <BR>
400487F34D6A161E4F76 var6 real10
33.9876 <BR><BR>DD和real4都可以在asm中来定义单精度浮点数,4 bytes
<BR>DQ和real8都可以在asm中来定义双精度浮点数,8 bytes <BR>DT和real10都可以在asm中来定义扩展精度浮点数,10 bytes
<BR>
<BR>
(二)浮点部件
<BR><BR>FPU从功能上分为两个部分:控制单元和运算单元,控制单元主要面向CPU,而算数单元负责具体算数运算.
<BR>FPU即浮点部件包括8个通用寄存器,5个错误指针寄存器和三个控制寄存器. <BR><BR>1)8个通用寄存器每个80
bit,形成一个寄存器堆栈,所有的计算结果都保存在寄存器堆栈中,其中数据全部是80位的扩展精度格式,即使是BCD,整数,单精度和双精度等在装入寄存器的时候都要被FPU自动转化为80位的扩展精度格式,注意栈顶通常表示为ST(0),然后是ST(1)...ST(i),ST(i)是相对于栈顶而言的.
<BR><BR>和堆栈很相似,只不过宽度为80bit,映像如下: <BR>
_______________________ <BR>
| ST(0)
| <BR>
|_______________________| <BR>
| ST(1) |
<BR> |_______________________|
<BR> |
...... | <BR>
| ......
| <BR> |
ST(i) |
<BR>
|_______________________| <BR><BR>2)控制寄存器,FPU有三个控制寄存器:状态寄存器,控制寄存器和标记寄存器
<BR><BR>状态寄存器->SW <BR>
_M_____D________10___9____8___7_________5_________________________0__
<BR> | B | C3| TOP| C2 | C1 | C0 | ES |
| PE | UE | OE | ZE | DE | IE | <BR>
|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
<BR><BR>B: 浮点部件正忙 <BR>C0-C3 指示浮点运算的结果,不同指令有不同含义
<BR>TOP 指示栈顶,通常是0 <BR>ES 以下任何位置位 (pe, ue, oe, ze, de, or ie) 则置位
<BR>PE 精度故障 <BR>UE 数字太小无法表示溢出 <BR>OE 现有精度无法表示,数字太大溢出 <BR>ZE
除0错 <BR>DE 指示至少有一个操作数未规格化 <BR>IE 无效错误,指示堆栈上溢或下溢,无效操作数等
<BR><BR><BR>控制寄存器: <BR>
_15____________10___9____8___7_________5______________________0__ <BR>
| |IC | RC |
PC | | PM | UM | OM | ZM | DM | IM | <BR>
|____|____|____|___|__|_|__|__|____|____|____|____|____|____|____|
<BR><BR>IC 无穷大控制,对486,已经无效 <BR>RC 舍入控制 <BR> 00 =
朝最接近或者偶数舍入 <BR> 01 = 朝负无穷大方向舍入 <BR>
10 = 朝</SPAN></SPAN><SPAN class=pediy>正无穷大方向舍入 <BR>
11 = 超0方向截断 <BR>PC 精度控制 <BR> 00 = 单精度
<BR> 01 = 保留 <BR> 10 =
双精度 <BR> 11 = 扩展精度 <BR>PM~IM 屏蔽状态寄存器低5位指示的错误.为1则屏蔽.
<BR><BR><BR>标记寄存器: <BR> 每2
bit表示一个对应堆栈寄存器的状态,具体含义如下: <BR>
15________________________________________3_____0 <BR>
|Tag7 |...................................|tag1| <BR>
|_____|___________________________________|____| <BR>
<BR>含义: <BR> 00 = 有效 <BR>
01 = 零 <BR> 10 = 无效或无穷大 <BR>
11 = 为空 <BR><BR>
</SPAN></BLOCKQUOTE>
<BLOCKQUOTE><SPAN class=pediy>(三)浮点指令系统及MASM下浮点程序设计
<BR><BR>事实上最重要和比较难于找到资料在(一)和(二)部分中已经介绍,下面是为了完整性的考虑,如果你是第一次接触浮点指令,看看下面的摘要也无妨.另外本文未涉及到的一个方面是关于浮点处理异常的情况,因为涉及到保护模式和中断、任务切换以及SEH等较多内容,我相信介绍之后只会令人更加迷惑,况且我现在似乎也无法把这几个问题完全说清除,一般我们几乎不需要知道这些.让我们先来看主要内容.
<BR><BR>关于浮点程序设计是一个大的话题,我只是提纲挈领地简述Masm32V7(/V6)中的设计方法,因为486以上的CPU内建了浮点部件所以可以在程序里直接使用浮点指令.下面是一个小例子:
<BR><BR>__MASMSTD equ 1 <BR>.386p <BR>.model flat, stdcall
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -