home *** CD-ROM | disk | FTP | other *** search
- CHAPTER 7 FLOATING POINT DEBUGGING
-
- If your machine has an 8087 or 80287 chip, D86 gives you the best
- facilities for debugging code for the chip (which I generically
- refer to as "the 87").
-
- The display of the 87's state can be obtained by pressing the
- Ctrl-F key. If you don't have an 87 in your system, you won't
- get the display.
-
- You can also display floating point numbers displayed in 86
- memory, by using the FD, FQ, and FT specifiers described in
- Chapter 6.
-
- In the displays of floating point numbers, both on the 87 stack
- and in 86 memory, I've taken great care to provide a display that
- is both readable and accurate. I rejected the algorithms for
- display found in the popular reference books on the subject,
- because they failed for several classes of extreme values.
-
-
- The Floating Point Display Window
-
- The floating point display you get with Ctrl-F contains the
- following components:
-
- 1. The top 8 lines contain the contents of each floating point
- register. The registers are displayed as a stack, with ST(0)
- on top, numbered with "0:". The format of the display depends
- on whether the number is a plain, normal number, or whether it
- is one of the exotic, non-normal types the 87 supports. I'll
- briefly describe the exotic types at the end of this chapter.
- The possible displays are:
-
- ---- (four hyphens), denoting a stack slot tagged empty.
-
- nnn a decimal number, displayed in scientific notation
- if necessary.
-
- Infinity for an overflowed result.
-
- NaN for Not a Number, followed by the hexadecimal codes
- of the significand field of the NaN
-
- Den for denormal, followed by the number of bits of
- precision lost, followed by the value of the
- number.
-
- Unn for unnormal, followed by the number of bits of
- precision lost, followed by the value of the
- number.
-
- Pseudo 0 for a pseudo zero, followed by the contents of the
- exponent field.
-
- 2. English-language displays for the infinity, precision, and
- rounding mode settings for the chip.
- 7-2
-
- 3. The value of the instruction pointer for the instruction that
- caused the last floating-point exception. If all exceptions
- are masked this doesn't change.
-
- 4. The address of the memory operand for the instruction that
- caused the last floating-point exception. If all exceptions
- are masked this doesn't change either.
-
- 5. The value of the Tag register, for registers 7 through 0.
- These register numbers are NOT the same as the stack element
- numbers-- they are rotated by the value of ST, given on the
- next line. The possible values for the Tag register fields
- are:
-
- f for finite non-zero number
- z for zero
- i for infinite number
- - for empty slot
-
- 6. The value of the stack pointer ST. The tag-register number
- for ST(i) is ST plus i.
-
- 7. A display of which 87 exceptions are masked; i.e., will not
- cause interrupts. If the exception is masked, its letter is
- displayed. If it is not masked (interrupt will occur), a
- blank is displayed. The letters are:
-
- p for precision exception
- u for underflow exception
- o for overflow exception
- z for zero-divide exception
- d for denormal exception
- i for invalid operation exception
-
- 8. A display of which masked exceptions have occurred since the
- last time the status bits were cleared. The exceptions have
- the same letters as the masked display.
-
- 9. A display of the 87 Condition Flags C3 through C0. A
- displaying character is shown if the flag is set; a blank is
- shown if the flag is cleared. The characters are:
-
- z for C3 (corresponds to the Zero flag)
- u for C2 (set if a result is "unordered")
- . for C1
- c for C0 (corresponds to the Carry flag)
-
- 10. Another display of C3 through C0, this time showing the
- results of an FXAM instruction. This display is always
- present, even when FXAM is not the last flag-setting
- instruction executed (in which case the display is
- meaningless).
- 7-3
-
- Exotic Flavors of Floating Point Numbers
-
- Some of the types of numbers possible in the floating point
- register display may seem a little strange to you if you haven't
- had much experience with the 87. It's a bit beyond the scope of
- this manual to go into detail about them-- you should consult a
- book such as "The 80286 Architecture" by Steve Morse for a
- detailed discussion. But here are brief descriptions to give you
- a bit of an idea of what's going on:
-
- NaN (Not-a-Number) values are used to represent results that are
- totally different than any floating-point number that could be
- provided. A specific NaN (with hex value C000 0000 0000 0000) is
- produced by the 87 whenever it can't cope with something, and the
- Invalid Operation exception is masked. Other NaN values might be
- loaded by a program from 86 memory, to be interpreted in any way
- the program chooses.
-
- For the rest of this discussion, let's introduce a little
- terminology. Floating point numbers use a format that follows
- the same principle as scientific notation. In scientific
- notation, one part of the number gives the significant digits of
- the number, always "normalized" to fall between 1 and 10. Another
- part of the number gives the magnitude of the number: the power
- of ten that you multiply the first part by, to get the true
- value. For example, 2.34 * 10**2 is a normal, scientific
- notation for 234. (It can be written in A86 as 2.34E2). 2.34 *
- 10**-2 is a normal scientific notation for 0.0234. Note that
- 0.234 * 10**-1 is a non-normal representation for the same
- number: we have increased the size of the exponent from -2 to -1,
- but the significant part is less than 1 instead of being between
- 1 and 10.
-
- In the 87 formats, everything is binary, with bits instead of
- digits. There is a "significand" field, normalized whenever
- possible so that the most significant bit is 1 (the value is
- between 1 and 2). There is the "exponent" field, giving the
- (positive or negative) power of two that you multiply the
- significand by, to get the true value.
-
- Denormals are produced when the result of an operation is non-
- zero, but is so tiny that its exponent is a negative number too
- small to be represented in the 15-bit exponent field of an 87
- register. There is a trick called "gradual underflow" that makes
- the best of the situation: the smallest possible exponent is
- given, together with leading zeroes in the significand to signal
- a further reduction in the exponent. Each leading zero means
- there is one less bit with which to represent the significand.
-
- You can see denormals in action by typing Ctrl-F to get the
- floating-point display, then typing the following commands to be
- executed immediately:
-
- FINIT
- FLD 10.0
- FLD 1.E-4931
- FDIV 1
- 7-4
-
- The result of the division is a denormal because 10 ** -4932 has
- a power-of-two exponent too small to be represented in the 15-bit
- exponent field of the 87 register. The display indicates that 2
- bits of precision have been lost-- two leading zeroes have been
- forced into the significand field of the number.
-
- Now press the F3 key to divide the number by another 10. Now 5
- bits of precision have been lost. If you keep pressing the F3
- key, you get more and more bits of precision lost. The loss in
- accuracy shows up in the number displayed. Eventually, all bits
- are lost, and the number collapses to zero.
-
- What happens when we multiply a denormal number by 10, instead of
- dividing it by 10? The number becomes big enough to no longer
- require the denormalization; but there's no way to recover the
- bits of precision that have been lost. To signal that bits have
- been lost, the 87 retains the leading zeroes in the significand.
- Numbers containing such zeroes without the minimum exponent are
- called "unnormals".
-
- A certain kind of unnormal is a "pseudo-zero", obtained when all
- the bits of precision are lost. This can happen when you
- multiply two unnormals. The number of leading zero bits
- (precision bits lost) of the answer is the sum of the bits lost
- of the operands. If the total is 64 bits or more, all precision
- is lost-- the significand is zero. But the exponent field is
- nonzero, which brands the number as strange-- a true zero has
- zeroes in the entire number, including the exponent field.
-
-