Search code examples
assemblyx86x87

Which bits in the x87 tag word does FFREE ST(i) modify?


This example was written in NASM:

section .bss
    var28: resb  28


section .text
    _main:

        ; Initialize
            finit
            fldpi
        ; Read Tag Word
            fstenv [var28]
            mov    ax, [var28 + 8] ; move the Tag Word to ax

At this point ax = 0011 1111 1111 1111, which means ST7 = 00 (valid), and the rest is 11 (empty).

The rest of the code:

        ; FFREE ST(i)

            ffree ST7 ; Sets tag for ST(i) to empty.
            ; Read Tag Word
                fstenv [var28]
                mov    ax, [var28 + 8] ; move the Tag Word to ax

At this point ax = 0011 1111 1111 1111 too.
My question is, shouldn't be ax = 1111 1111 1111 1111?


Solution

  • At this point ax = 0011 1111 1111 1111, which means ST7 = 00 (valid), and the rest is 11 (empty).

    No. The Tag Word refers to the registers (R7..R0), while ST(i) refers to the "top of the stack" (TOS) which can change.

    The first fldpi sets the TOS (=ST(0)) to register R7 and loads PI into that register. A second fld would change the TOS to register R6 and fill that register. ST(0) would point then to the register of the second fld. ffree st0 would free R6 (the second tag in the Tag Word) and set ST0 to R7. The Status Word contains a three-bit number with the register to which the TOS currently points.

    In your example program, fldpi loads PI into ST(0) which points to R7. To empty R7 you have to use ffree st0.

    Please take a look to Chapter 8 of the Intel Manual Vol. 1 where it is discussed in detail.