Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6247681
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T12:55:16+00:00 2026-05-24T12:55:16+00:00

As part of a compiler project I have to write GNU assembler code for

  • 0

As part of a compiler project I have to write GNU assembler code for x86 to compare floating point values. I have tried to find resources on how to do this online and from what I understand it works like this:

Assuming the two values I want to compare are the only values on the floating point stack, then the fcomi instruction will compare the values and set the CPU-flags so that the je, jne, jl, … instructions can be used.

I’m asking because this only works sometimes. For example:

.section    .data
msg:    .ascii "Hallo\n\0"
f1:     .float 10.0
f2:     .float 9.0

.globl main
    .type   main, @function
main:
    flds f1
    flds f2
    fcomi
    jg leb
    pushl $msg
    call printf
    addl $4, %esp
leb:
    pushl $0
    call exit

will not print “Hallo” even though I think it should, and if you switch f1 and f2 it still won’t which is a logical contradiction. je and jne however seem to work fine.

What am I doing wrong?

PS: does the fcomip pop only one value or does it pop both?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T12:55:17+00:00Added an answer on May 24, 2026 at 12:55 pm

    TL:DR: Use above / below conditions (like for unsigned integer) to test the result of compares.

    For various historical reasons (mapping from FP status word to FLAGS via fcom / fstsw / sahf which fcomi (new in PPro) matches), FP compares set CF, not OF / SF. See also http://www.ray.masmcode.com/tutorial/fpuchap7.htm

    Modern SSE/SSE2 scalar compares into FLAGS follow this as well, with [u]comiss / sd. (Unlike SIMD compares, which have a predicate as part of the instruction, as an immediate, since they only produce a single all-zeros / all-ones result for each element, not a set of FLAGS.)


    This is all coming from Volume 2 of Intel 64 and IA-32 Architectures Software Developer’s Manuals.

    FCOMI sets only some of the flags that CMP does. Your code has %st(0) == 9 and %st(1) == 10. (Since it’s a stack they’re loaded onto), referring to the table on page 3-348 in Volume 2A you can see that this is the case "ST0 < ST(i)", so it will clear ZF and PF and set CF. Meanwhile on pg. 3-544 Vol. 2A you can read that JG means "Jump short if greater (ZF=0 and SF=OF)". In other words it’s testing the sign, overflow and zero flags, but FCOMI doesn’t set sign or overflow!

    Depending on which conditions you wish to jump, you should look at the possible comparison results and decide when you want to jump.

    +--------------------+---+---+---+
    | Comparison results | Z | P | C |
    +--------------------+---+---+---+
    | ST0 > ST(i)        | 0 | 0 | 0 |
    | ST0 < ST(i)        | 0 | 0 | 1 |
    | ST0 = ST(i)        | 1 | 0 | 0 |
    | unordered          | 1 | 1 | 1 |  one or both operands were NaN.
    +--------------------+---+---+---+
    

    I’ve made this small table to make it easier to figure out:

    +--------------+---+---+-----+------------------------------------+
    | Test         | Z | C | Jcc | Notes                              |
    +--------------+---+---+-----+------------------------------------+
    | ST0 < ST(i)  | X | 1 | JB  | ZF will never be set when CF = 1   |
    | ST0 <= ST(i) | 1 | 1 | JBE | Either ZF or CF is ok              |
    | ST0 == ST(i) | 1 | X | JE  | CF will never be set in this case  |
    | ST0 != ST(i) | 0 | X | JNE |                                    |
    | ST0 >= ST(i) | X | 0 | JAE | As long as CF is clear we are good |
    | ST0 > ST(i)  | 0 | 0 | JA  | Both CF and ZF must be clear       |
    +--------------+---+---+-----+------------------------------------+
    Legend: X: don't care, 0: clear, 1: set
    

    In other words the condition codes match those for using unsigned comparisons. The same goes if you’re using FMOVcc.

    If either (or both) operand to fcomi is NaN, it sets ZF=1 PF=1 CF=1. (FP compares have 4 possible results: >, <, ==, or unordered). If you care what your code does with NaNs, you may need an extra jp or jnp. But not always: for example, ja is only true if CF=0 and ZF=0, so it will be not-taken in the unordered case. If you want the unordered case to take the same execution path as below or equal, then ja is all you need.


    Here you should use JA if you want it to print (ie. if (!(f2 > f1)) { puts("hello"); }) and JBE if you don’t (corresponds to if (!(f2 <= f1)) { puts("hello"); }). (Note this might be a little confusing due to the fact that we only print if we don’t jump).


    Regarding your second question: by default fcomi doesn’t pop anything. You want its close cousin fcomip which pops %st0. You should always clear the fpu register stack after usage, so all in all your program ends up like this assuming you want the message printed:

    .section    .rodata
    msg:    .ascii "Hallo\n\0"
    f1:     .float 10.0
    f2:     .float 9.0 
    
    .globl main
        .type   main, @function
    main:
        flds   f1
        flds   f2
        fcomip
        fstp   %st(0) # to clear stack
        ja     leb # won't jump, jbe will
        pushl  $msg
        call   printf
        addl   $4, %esp
    leb:
        pushl  $0
        call   exit
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

As part of a university project, we have to write a compiler for a
As part of my Final Year Project, I need to convert some FORTRAN code
Part of my project wrote all their code in C#. Our web application is
I'm writing a yacc file as part of a compiler. I have the following
Part of a new product I have been assigned to work on involves server-side
Part of my latest webapp needs to write to file a fair amount as
I have a specific project in which I want to use either a scripting
We are working on a project to learn how to write a kernel and
I’m currently working on a reporting library as part of a large project. It
In my current project, I need to compile java code at runtime (in the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.