fcom/fcompp and fstatsw different results

31 Views Asked by At

I just starting using FPU and found some interesting moment. Correct me if I'm wrong, we have only 8 ST's (0-7). We can operate with only 8 float values with them. Here is the simple code:

fldz; ST0 = 0
fld1; ST0 = 1, ST1 = 0
fcompp
fstatsw ax

The value of the AX depends (in my case) on count of stored values in ST's. I have to get 0 at the AX, and it is if I call it in the begin of my code. But after some calculation using the FPU commands I started to get interesting values (if ST0 greater then ST1):

count | AX
------+------
    2 | 4000h
    3 | 3800h
    4 | 3000h
    5 | 2800h
    6 | 2000h
    7 | 1800h
    8 | 1000h

In other words, if I have 2 elements in ST's the result is 4000h; 3 elements - 3800h and etc. And we compare ST0 and ST1 always.

How it possible? Or I might forget something? For other comparison results (equal and less then), I see the same behavior, but with another numbers.

If ST0 equal ST1:

count | AX
------+------
    2 | 8000h
    3 | 7800h
    4 | 7000h
    5 | 6800h
    6 | 6000h
    7 | 5800h
    8 | 5000h

If ST0 less then ST1:

count | AX
------+------
    2 | 4100h
    3 | 3900h
    4 | 3100h
    5 | 2900h
    6 | 2100h
    7 | 1900h
    8 | 1100h

Environment:

Assembler: FASM
CPU: x64
Application: Windows GUI x86
1

There are 1 best solutions below

3
Iridium On

The FPU status word you're storing in ax includes the "top of stack" register number, so will change depending on the number of items in the register stack as well as the result of your fcompp instruction. If you want to inspect the status word to determine the result of the comparison you will need to extract the appropriate bits.

Note that if you want to use conditional branching instructions (Jcc) based on the result of the floating point comparison you may want to look at using one of the floating point comparison instructions that sets the regular EFLAGS register, e.g. fcomip.