2024年3月31日发(作者:)

FPU详解

目录

第零章: 简介

第一章: FPU 内部解说

第二章: FPU 使用的数据类型和寻址方式

第三章: 与FPU 内部有关的指令

第四章: 数据传输指令-实数

第五章: 数据传输指令-整数

第六章: 数据传输指令-压缩十进制数

第七章: 比较指令

第八章: 算术运算指令-用于实数

第九章: 算术运算指令-用于整数

第十章: 三角函数指令

第十一章:对数和指数指令

第十二章:其它指令

第十三章:解说例子

附录 1: FPU 同义指令表

第零章 简介

FPU,也被称为协处理器,当第一部PC 走进超市时它还是可选的,而现代PC 都配置

了一个协处理器。尽管原来的PC-XT 在几年间就大大进步了,但FPU 本身在同个时代并

没有作出相应的改变。除了增加一些很少的指令外,主要的改善还是在于扩充一些已有的指

令。

整个FPU 汇编指令集相对来说比较少并且容易记忆,但学习那个参数能用于那条指令

则应该较花时间一点。在开发中的主要困难在于合理地使用编程技术来避免一些FPU 所特

有的错误陷阱。

这份文档的主要目的在于展示用最小的努力也能相对容易地学习到FPU 的使用。一旦

掌握了基础,任何复杂的计算都能完成。

第一章描述了FPU 内部和它们是怎样运行的,有些知识对于适当地使用FPU 来说是绝

对需要的,有些则帮助理解后面一些指令的输出。随后的一章讲述各种各样的数据类型和那

些数据能用于那些指令,包括一份对浮点数据格式的详细论述。

FPU 指令在稍后几章中详细说明,这些章节都是根据一些“偏向”条件进行重新组合

的。尽管每条指令的解说都能在MASM32 里提供的 文件里找到,但本文提供了

更多关于使用它们的现实例子来进行更深入的讨论。

最后一章提供了对一个半复数计算例子的完整解说。

值得注意的是这份文档是为使用MASM 语法而准备的。尽管有许多汇编器/编译器都为

FPU 指令的助记提供了相似的语法,但在内存变量的寻址模式上可能有所不同。也就是说

有些不需要显式参数的指令可能在其它的汇编器/编译器上不支持。

第一章 FPU内部解说

FPU 仅仅有8 个相同的80 位寄存器和3 个16 位寄存器(控制字、状态字、特征字)

可供程序员访问,它也同样有一个程序员不能访问的内部标志寄存器。

80 位寄存器

80 位寄存器在许多文献里被称为有8 个寄存器的栈。为了更好地理解这几个80 位寄

存器的功能,以其将它们想象成一个堆栈,不如将它们想象成一个有8 个子弹筒的从顺时

针方向由0 到7 排列的左轮枪筒或许更容易理解一些。当FPU 初始化之后,所有的子弹筒

为空并且子弹筒0(BC0)会被置于12 点整的位置(也就是最顶部),如下面的图1.1 所示:

注意:这些子弹筒(BC)数字是FPU 内部严格使用的,它们像CPU 中的EAX、EBX 等

等一样用于将每个筒标识为一个物理单元(并不是为了旋转枪筒也不是所有的堆栈都像FPU

这样)。

当FPU 指示要装入一个值时,它会旋转枪筒一个槽位并将指定的值装入最顶部的筒里。

如果第一个值在FPU 初始化好后立即载入,根据FPU 内部的编号系统它会因此被装入到

BC7 里。

如果FPU 当第一个值仍然在BC7 里而又想再装入另一个值的话,它会再次顺时针方向

旋转枪筒一个槽位并再次将指定的值装入最顶部的筒里,也就是当前的BC6。

数值只会装入FPU 最顶部的筒里

这种情况会一直持续下去直到所有的筒都包含了一个值。如果,无论如何,当所有的子

弹筒都包含一个值时还想尝试装入一个值的话,枪筒仍然会旋转一个槽位但装入试验会失败

(就像在一个已经有子弹的筒里再想插入一个子弹一样)。并且,不管那个筒里装了任何有

效的值,最顶部的筒现在都已经被破坏了。留下了不可用的废物在最顶部的寄存器里。

规则1:一个80 位的FPU 寄存器为了能装入一个值必须为空

还好,可以用各种各样的FPU 指令来清空这些寄存器。最通用的方法通常都是一句“弹

出一个寄存器”。“POP”助记符已经用在了CPU中而对FPU 无效。作为替换,FPU 包含了

很多指令;这样的指令会正常地输出一个值然后立即在最顶部弹出一个寄存器。

当FPU 指示弹出一个值时,不管当前那个筒在最顶部,它都会首先将它移除并将枪筒