ax
register is always the ax
register, no matter what happens. On the 80x87, however, the register set is an eight element stack of 80 bit floating point values (see the figure below). ST(0) refers to the item on the top of the stack, ST(1) refers to the next item on the stack, and so on. Many floating point instructions push and pop items on the stack; therefore, ST(1) will refer to the previous contents of ST(0) after you push something onto the stack. It will take some thought and practice to get used to the fact that the registers are changing under you, but this is an easy problem to overcome.
Bit 12 of the control register is only present on the 8087 and 80287 chips. It controls how the 80x87 responds to infinity. The 80387 and later chips always use a form of infinitly known and affine closure because this is the only form supported by the IEEE 754/854 standards. As such, we will ignore any further use of this bit and assume that it is always programmed with a one.
Bits 10 and 11 provide rounding control according to the following values:
Bits 10 & 11 | Function |
---|---|
00 | To nearest or even |
01 | Round down |
10 | Round up |
11 | Truncate |
Bits 8 & 9 | Precision Control |
---|---|
00 | 24 bits |
01 | Reserved |
10 | 53 bits |
11 | 64 bits |
Bits zero through five are the exception flags. These bits are appear in the same order as the exception masks in the control register. If the corresponding condition exists, then the bit is set. These bits are independent of the exception masks in the control register. The 80x87 sets and clears these bits regardless of the corresponding mask setting.
Bit six (active only on 80386 and later processors) indicates a stack fault. A stack fault occurs whenever there is a stack overflow or underflow. When this bit is set, the C1 condition code bit determines whether there was a stack overflow (C1=1) or stack underflow (C1=0) condition.
Bit seven of the status register is set if any error condition bit is set. It is the logical OR of bits zero through five. A program can test this bit to quickly determine if an error condition exists.
Bits eight, nine, ten, and fourteen are the coprocessor condition code bits. Various instructions set the condition code bits as shown in the following table:
Instruction | Condition Code Bits C3 C2 C1 C0 |
Condition |
---|---|---|
fcom, fcomp, fcompp, ficom, ficomp | 0 0 X 0 0 0 X 1 1 0 X 0 1 1 X 1 |
ST > source ST < source ST = source ST or source undefined |
ftst | 0 0 X 0 0 0 X 1 1 0 X 0 1 1 X 1 |
ST is positive ST is negative ST is zero (+ or -) ST is uncomparable |
fxam | 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 1 0 0 1 1 0 1 0 1 0 1 1 1 1 X X 1 |
+ Unnormalized -Unnormalized +Normalized -Normalized +0 -0 +Denormalized -Denormalized +NaN -NaN +Infinity -Infinity Empty register |
fucom, fucomp, fucompp | 0 0 X 0 0 0 X 1 1 0 X 0 1 1 X 1 |
ST > source ST < source ST = source Unorder |
X = Don't care |
Insruction(s) | C0 | C3 | C2 | C1 |
---|---|---|---|---|
fcom, fcomp, fcmpp, ftst, fucom, fucomp, fucompp, ficom, ficomp | Result of comparison. See table above. |
Result of comparison. See table above. |
Operand is not comparable. |
Result of comparison (see table above) or stack overflow/underflow (if stack exception bit is set ). |
fxam | See previous table. | See previous table. | See previous table. | Sign of result, or stack overflow/underflow (if stack exception bit is set ). |
fprem, fprem1 | Bit 2 of remainder | Bit 0 of remainder | 0- reduction done. 1- reduction incomplete. |
Bit 1 of remainder or stack overflow/underflow (if stack exception bit is set ). |
fist, fbstp, frndint, fst, fstp, fadd, fmul, fdiv, fdivr, fsub, fsubr, fscale, fsqrt, fpatan, f2xm1, fyl2x, fyl2xp1 | Undefined |
Undefined |
Undefined |
Round up occurred or stack overflow/underflow (if stack exception bit is set ). |
fptan, fsin, fcos, fsincos | Undefined |
Undefined |
0- reduction done. 1- reduction incomplete. |
Round up occurred or stack overflow/underflow (if stack exception bit is set ). |
fchs, fabs, fxch, fincstp, fdecstp, constant loads, fxtract, fld, fild, fbld, fstp (80 bit) | Undefined |
Undefined |
Undefined |
Zero result or stack overflow/underflow (if stack exception bit is set ). |
fldenv, fstor | Restored from memory operand. | Restored from memory operand. | Restored from memory operand. | Restored from memory operand. |
fldcw, fstenv, fstcw, fstsw, fclex | Undefined |
Undefined |
Undefined |
Undefined |
finit, fsave | Cleared to zero. | Cleared to zero. | Cleared to zero. | Cleared to zero. |
The 80x87 FPU generally stores values in a normalized format. When a floating point number is normalized, the H.O. bit is always one. In the 32 and 64 bit floating point formats, the 80x87 does not actually store this bit, the 80x87 always assumes that it is one. Therefore, 32 and 64 bit floating point numbers are always normalized. In the extended precision 80 bit floating point format, the 80x87 does not assume that the H.O. bit of the mantissa is one, the H.O. bit of the number appears as part of the string of bits.
Normalized values provide the greatest precision for a given number of bits. However, there are a large number of non-normalized values which we can represent with the 80 bit format. These values are very close to zero and represent the set of values whose mantissa H.O. bit is not zero. The 80x87 FPUs support a special form of 80 bit known as denormalized values. Denormalized values allow the 80x87 to encode very small values it cannot encode using normalized values, but at a price. Denormalized values offer less bits of precision than normalized values. Therefore, using denormalized values in a computation may introduce some slight inaccuracy into a computation. Of course, this is always better than underflowing the denormalized value to zero (which could make the computation even less accurate), but you must keep in mind that if you work with very small values you may lose some accuracy in your computations. Note that the 80x87 status register contains a bit you can use to detect when the FPU uses a denormalized value in a computation.