设为首页 加入收藏

TOP

8.2.3 控制寄存器
2013-10-07 00:51:39 来源: 作者: 【 】 浏览:50
Tags:8.2.3 控制 寄存器

8.2.3  控制寄存器

在浮点运算中,需要控制的一般就是计算精度、舍入模式和异常,因此控制寄存器非常简洁,如图8-4所示。

对应的异常大多在5.3中已经讲述,唯一没有提到的是无穷控制位(Infinity Control)对应的异常,这是80287数学协处理器的遗迹(我始终没有弄明白,80287数学协处理器怎么用这个位),在IA-32体系中已没有用处。

编写控制寄存器的操作代码需要非常小心,最常见的错误是在设置一个域时无意中改变了另一个域,例如下列代码:

  1. controls = EM_PRECISION;        // 屏蔽精度异常  
  2. __asm FLDCW  controls          // 设置 
这段代码的目的是屏蔽精度异常,但实际上它也同时清除了对其他异常的屏蔽以及精度设置和舍入模式设置。更为麻烦的是,改变精度设置和舍入模式导致的计算精度不够或错误是很难察觉的。避免这种错误的基本方法就是对控制寄存器操作提供标准函数,不允许其他代码操作控制寄存器。
 

(1)指令

控制寄存器可以读写,有两条指令,即载入指令FLDCW和存储指令FSTCW,两者的操作数均是16位内存单元。代码示例如下:

  1. unsigned short controls;  
  2. __asm FLDCW controls  
  3. __asm FSTCW controls  
  4. __asm FLDCW WORD PTR [ESP+4] 

(2)异常屏蔽位

控制寄存器的低6位用于控制6种异常的屏蔽,设置相应位即可屏蔽异常。为了方便操作,可以定义一组常量:

  1. #define EM_MASK                     0x3F  
  2. #define EM_INVALID_OPERATION      0x01  
  3. #define EM_DENORMAL_OPERAND     0x02  
  4. #define EM_ZERO_DIVIDE              0x04  
  5. #define EM_OVERFLOW                0x08  
  6. #define EM_UNDERFLOW              0x10  
  7. #define EM_PRECISION                 0x20 
那么屏蔽精度异常的嵌入式代码就是:
  1. unsigned short controls;  
  2. __asm FSTCW  controls             // 获取控制寄存器内容  
  3. controls |= EM_PRECISION;          // 屏蔽精度异常  
  4. __asm FLDCW  controls             // 设置  
  5. 清除代码就是:  
  6. unsigned short controls;  
  7. __asm FSTCW  controls            // 获取控制寄存器内容  
  8. controls &= ~EM_PRECISION;       // 清除精度异常  
  9. __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

同样可以定义常量:

  1. #define PC_MASK                 0x300  
  2. #define PC_FLOAT_24             0x000  
  3. #define PC_RESERVED             0x100  
  4. #define PC_DOUBLE_53            0x200  
  5. #define PC_EX_DOUBLE_64         0x300 
使用扩展双精度的设置代码:
  1. unsigned short controls;  
  2. __asm FSTCW  controls          // 获取控制寄存器内容  
  3. controls &= ~PC_MASK;          // 清零,否则可能设置错误!  
  4. controls |= PC_EX_DOUBLE_64    // 64位精度  
  5. __asm FLDCW  controls          // 设置 

(4)舍入模式

x87 FPU均支持4.1.3节曾讨论的4种舍入模式,控制寄存器的位10和位11控制舍入模式的选择见表8-2。

表8-2  x87 FPU的舍入控制位

舍入模式

RC

最近舍入

00B

-∞舍入

01B

+∞舍入

10B

0舍入(截断舍入)

11B

同样可以定义常量:

  1. #define RC_MASK0                0xC00  
  2. #define RC_NEAREST0             0x000  
  3. #define RC_DOWN0                0x400  
  4. #define RC_UP0                  0x800  
  5. #define RC_TRUNCATE0            0xC00 

使用最近舍入模式的设置代码:

  1. unsigned short controls;  
  2. __asm FSTCW  controls         // 获取控制寄存器内容  
  3. controls &= ~RC_MASK;         // RC位清零即是最近舍入  
  4. __asm FLDCW  controls         // 设置 
【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇8.2.4 其他寄存器 下一篇8.2.2 状态寄存器

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: