ITEEDU

11.2.2 状态寄存器

状态寄存器是用来标识协处理器中指令执行情况的,它相当于CPU中的标志位寄存器。80x87协处理器的状态寄存器如图11.5所示。

15   13 12 11     8 7             0
B C3 TOP C2 C1 C0 ES SF PE UE OE ZE DE IE
图11.5 80x87协处理器的状态寄存器示意图

状态寄存器各标志位(或组合位)的含义如下:

◆ B(Busy,忙)

忙标志位用来表明协处理器是否正在执行协处理器指令,它可用FWAIT指令来测试。在80287及其以后的协处理器中,协处理器和CPU能自动实现同步,所以,现在在运行任务时,无须测试忙标志。

◆ C3~C0(条件编码位)

四位条件编码位的组合含义如表11.2所列。

表11.2 状态寄存器中条件编码位的组合含义

指 令

C3

C2

C1

C0

功 能

FTST、FCOM

0

0

X

0

 ST>操作数或(0 FTST)

0 0 X 1  ST<操作数或(0 FTST)
1 0 X 0  ST=操作数或(0 FTST)
1 1 X 1  ST不可比较

FPREM

Q1 0 Q0 Q2  Q2Q1Q0是商的右边3位
  1      未完成

FXAM

0 0 0 0  +unnormal
0 0 0 1  +NAN
0 0 1 0  -unnormal
0 0 1 1  -NAN
0 1 0 0  +normal
0 1 0 1  +∞
0 1 1 0  -unnormal
0 1 1 1  -∞
1 0 0 0  +0
1 0 0 1  空
1 0 1 0  -0
1 0 1 1  空
1 1 0 0  +denormal
1 1 0 1  空
1 1 1 0  -denormal
1 1 1 1  空

其中,normal—标准的浮点数,unnormal—有效数字前面是0,如:0.XXXX,denormal—阶码是最大的负值,NAN—见11.1.3节中几个特殊数据的说明。

◆ TOP(栈顶)

该三位二进制000~111用来表明当前作为栈顶的寄存器,通常其值为000。

◆ ES(错误汇总)

ES=PE+UE+OE+ZE+DE+IE(逻辑或运算),在8087协处理器中,当ES为1时,将发出一个协处理器中断请求,但在其后的协处理器中,不再产生这样的协处理器中断申请。

◆ SF(堆栈溢出错误)

该状态位用来表明协处理器内部的堆栈是否有上溢或下溢错误。

◆ PE(精度错误)

该状态位用来表明运算结果或操作数是否超过先前设定的精度。

◆ UE(下溢错误)

该状态位用来表明一个非0的结果太小,不能用控制字节所选定的当前精度来表示。

◆ OE(上溢错误)

该状态位用来表明一个非0的结果太大,不能用控制字节所选定的当前精度来表示,即超过了当前精度所能表示的数据范围。

如果在控制寄存器中屏蔽该错误标志,即设控制寄存器中的OM为1,那么,协处理器把上溢结果定义为无穷大。

◆ ZE(除法错误)

该状态位用来表明当前执行了“0作除数”的除法运算。

◆ DE(非规格化错误)

该状态位用来表明当前参与运算的操作数中至少有一个操作数是没有规格化的。

◆ IE(非法错误)

该状态位用来表明执行了一个错误的操作,如:求负数的平方根,也可用来表明堆栈的溢出错误、不确定的格式(0/0,∞,-∞等)错误,或用NAN作为操作数。

对于协处理器中状态寄存器的内容,程序员可用指令FSTSW把其值送到内存单元中。如果当前使用的是80287及其以后的协处理器,那么,可用指令“FSTSW AX”把该状态寄存器的值传送给通用寄存器AX。一旦状态寄存器的值复制到内存或AX中,那么,就可对其各位进行分析,并可检测出当前协处理器的工作状态。

对于80287协处理器,它还可通过I/O地址00FAH~00FFH来实现其与CPU之间的数据交换,而80387~Pentium系列芯片,则是通过I/O地址800000FAH~800000FFH来实现这两者之间的数据交换。

当状态寄存器的内容传给AX之后,一般可用下面二种方法来检测协处理器的状态。

方法1:用TEST指令来检测其相应的状态位。
例11.3 检测是否有“0作除数”的错误。 
FDIV DATA1 ;用协处理器中堆顶数据去除DATA1

FSTSW AX ;把状态寄存器的值传送给AX

TEST AX, 4 ;测试第2位,即:检测ZE是否为1

JNZ DIV_ERR
例11.4 检测是否有“非法操作数”的错误。 
FSQRT ;求协处理器中堆顶数据的平方根 

FSTSW AX

TEST AX, 1 ;测试第0位,即:检测IE是否为1

JNZ SQRT_ERR
方法2:用SAHF指令把AX的低字节传送给CPU的标志位寄存器,然后再用条件转移指令来完成相应的检测。 
例11.5 检测内存单元的数据与协处理器堆顶数据之间的大小关系。 
FCOM DATA1 ;内存单元DATA1的值与协处理器堆顶数据进行比较 

FSTSW AX

SAHF ;把AX的低字节存入CPU的状态寄存器 

JE ST_EQUAL;具体大小关系的决定可见表11.2中的“FCOM”

JB ST_BELOW

JA ST_ABOVE