Advertisement

FCom and other ASM floating-point stuff

Started by November 25, 2000 10:13 PM
5 comments, last by CGameProgrammer 24 years, 2 months ago
How does this work? I tried something like:

void test ( )
{
    float Var = 0.5f;
    float Min = 0.0f;
    float Max = 1.0f;
    BYTE  Success;

    _asm
    {
        FLD   Var // ST(0) = Var
        FComP Min // Compare Var to Min
        JG    Successful

        Mov   Success, 0
        Jmp   Done

Successful:

        Mov   Success, 1

Done:
    }

    printf( "Success: %i", (int)Success );
}
After I ran that, Success == 1. So it worked. But this did not:

void test ( )
{
    float Var = 0.5f;
    float Min = 0.0f;
    float Max = 1.0f;
    BYTE  Success;

    _asm
    {
        FLD   Var // ST(0) = Var
        FComP Max // Compare Var to Max
        JL    Successful

        Mov   Success, 0
        Jmp   Done

Successful:

        Mov   Success, 1

Done:
    }

    printf( "Success: %i", (int)Success );
}
Success == 0 after I ran this test, even though 0.5 is less than 1.0. So what am I doing wrong? ~CGameProgrammer( );

~CGameProgrammer( ); Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
I cant really answer your question but I have a question to ask you after you declare all of your float numbers such as:

float Var = 0.5f;

What does the f stand for after the 0.5 and what does it do?
Advertisement
Also is it necessary to put the f?
The f isn''t necessary, but it doesn''t hurt anything. It is the same as writing (float) 0.5. That was for the AP''s reference, I don''t do assembly very well, you don''t want my advice, trust me =P.


http://www.gdarchive.net/druidgames/
Okay, what it comes down to is that the FPU doesn''t affect the normal interger flags - this means that infact neither routine works (try some different numbers in the that should cause a different result and you should find that the same behaviour occurs). The way you need to do this is to use ''fnstsw ax'' to retrieve the FPU status flags, then test ax for the flags. Here are the re-written versions of your code:

  // first routine (testing for greater than)void test ( ){   float Var = 0.5f;   float Min = 0.0f;   float Max = 1.0f;   BYTE  Success;       _asm   {      FLD   Var // ST(0) = Var      FComP Min // Compare Var to Min      FNSTSW ax // get FPU status word into register ax      test   al, 65 // check less-than bit (bit 1 of status) and eqaul bit (bit 6 of status)      jz    Sucessful // if both bits are 0, then Var was greater than Max      Mov   Success, 0      Jmp   DoneSuccessful:      Mov   Success, 1Done:   }       printf( "Success: %i", (int)Success );}// second routine (testing for less than)void test ( ){   float Var = 0.5f;   float Min = 0.0f;   float Max = 1.0f;   BYTE  Success;   _asm   {      FLD   Var // ST(0) = Var      FComP Max // Compare Var to Max      FNSTSW ax	// get FPU status      test   al, 1	// check less-than bit      jnz    Sucessful // if bit is not zero, then Var is less than max      Mov   Success, 0      Jmp   DoneSuccessful:      Mov   Success, 1Done:   }       printf( "Success: %i", (int)Success );}  


I suggest that you should try playing with these routines, using different numbers to check that they work - also try some cases that should fail !!!

"Falsification is the only true test of a theory", or so I was told in philosophy

Hope this helps you a bit
Heh, I forgot that in situations like this, simply having the compiler create assembly output of C++ code lets me see how it''s done. The compiler did what you did, last Anon Poster, but it tested AH instead of AL. So I used AH and it works.

~CGameProgrammer( );

~CGameProgrammer( ); Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Advertisement
Ahhh, can you believe it, I checked what I''d written in some previous code...then managed to copy it down incorrectly...oh well, glad you found the correct register...goes to show that I aught to proof read my posts (and get round to registering).

Anyhow, I''m glad it''s working now

Nick B

This topic is closed to new replies.

Advertisement