# Category : Assembly Language Source Code

Archive : D86V372.ZIP

Filename : D07.DOC

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.

Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/