8.2.3 控制寄存器
在浮点运算中,需要控制的一般就是计算精度、舍入模式和异常,因此控制寄存器非常简洁,如图8-4所示。
对应的异常大多在5.3中已经讲述,唯一没有提到的是无穷控制位(Infinity Control)对应的异常,这是80287数学协处理器的遗迹(我始终没有弄明白,80287数学协处理器怎么用这个位),在IA-32体系中已没有用处。
编写控制寄存器的操作代码需要非常小心,最常见的错误是在设置一个域时无意中改变了另一个域,例如下列代码:
- controls = EM_PRECISION;
- __asm FLDCW controls
这段代码的目的是屏蔽精度异常,但实际上它也同时清除了对其他异常的屏蔽以及精度设置和舍入模式设置。更为麻烦的是,改变精度设置和舍入模式导致的计算精度不够或错误是很难察觉的。避免这种错误的基本方法就是对控制寄存器操作提供标准函数,不允许其他代码操作控制寄存器。
(1)指令
控制寄存器可以读写,有两条指令,即载入指令FLDCW和存储指令FSTCW,两者的操作数均是16位内存单元。代码示例如下:
- unsigned short controls;
- __asm FLDCW controls
- __asm FSTCW controls
- __asm FLDCW WORD PTR [ESP+4]
(2)异常屏蔽位
控制寄存器的低6位用于控制6种异常的屏蔽,设置相应位即可屏蔽异常。为了方便操作,可以定义一组常量:
- #define EM_MASK 0x3F
- #define EM_INVALID_OPERATION 0x01
- #define EM_DENORMAL_OPERAND 0x02
- #define EM_ZERO_DIVIDE 0x04
- #define EM_OVERFLOW 0x08
- #define EM_UNDERFLOW 0x10
- #define EM_PRECISION 0x20
那么屏蔽精度异常的嵌入式代码就是:- unsigned short controls;
- __asm FSTCW controls
- controls |= EM_PRECISION;
- __asm FLDCW controls
- 清除代码就是:
- unsigned short controls;
- __asm FSTCW controls
- controls &= ~EM_PRECISION;
- __asm FLDCW controls
(3)精度控制
x87 FPU支持三种IEEE类型,即单精度、双精度和扩展双精度,对应的就有三种计算精度,即24位、53位和64位。控制寄存器中的PC位(位8和位9)控制使用的精度,见表8-1。
表8-1 x87 FPU的精度控制位
|
精度< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
PC位 |
|
IEEE单精度24位 |
00B |
|
保留 |
01B |
|
IEEE双精度53位 |
10B |
|
IEEE扩展双精度64位 |
11B |
同样可以定义常量:
- #define PC_MASK 0x300
- #define PC_FLOAT_24 0x000
- #define PC_RESERVED 0x100
- #define PC_DOUBLE_53 0x200
- #define PC_EX_DOUBLE_64 0x300
使用扩展双精度的设置代码:- unsigned short controls;
- __asm FSTCW controls
- controls &= ~PC_MASK;
- controls |= PC_EX_DOUBLE_64
- __asm FLDCW controls
(4)舍入模式
x87 FPU均支持4.1.3节曾讨论的4种舍入模式,控制寄存器的位10和位11控制舍入模式的选择见表8-2。
表8-2 x87 FPU的舍入控制位
|
舍入模式 |
RC位 |
|
最近舍入 |
00B |
|
向-∞舍入 |
01B |
|
向+∞舍入 |
10B |
|
向0舍入(截断舍入) |
11B |
同样可以定义常量:
- #define RC_MASK0 0xC00
- #define RC_NEAREST0 0x000
- #define RC_DOWN0 0x400
- #define RC_UP0 0x800
- #define RC_TRUNCATE0 0xC00
使用最近舍入模式的设置代码:
- unsigned short controls;
- __asm FSTCW controls
- controls &= ~RC_MASK;
- __asm FLDCW controls
【责任编辑:
董书 TEL:(010)68476606】