Question

At my university we are introduced to IA32/x86 assembler with AT&T Syntax. But the explanation lacks of important information.

How am I able to move a 4 byte float from the stack to the FPU? I tried with flds but it didn't work as expected...

EXAMPLE CODE:

.data
        fl:     .float 12.412
        test:   .string "Result: %f\n"

.text
.global main

main:
        # Prepare the stack (8 byte so i can use it for printf later)
        subl $8, %esp
        # Load the variable fl which holds 12.412
        fld fl
        # Store the previously loaded value as single precision (4 byte) to the stack
        fstps (%esp)
        # Load the value from the stack again and expect it to be single precision (as flds ends with s)
        flds (%esp)


        # Push it to the stack again. But this time as double precision value als printf expects floats to be 8 bytes long 
        fstp (%esp)
        pushl $test
        call printf

        movl $1, %eax
        int $0x80

But the output is:

Result: -0.491594

and not 12.412 as expected...

[EDIT:] Funny fact. Surprisingly the result changes for every single execution of the program.

Was it helpful?

Solution

I think the problem is that (right before you call printf) you use the wrong instruction to pop the FPU's top onto the stack. Your comment says "...this time as double precision...", but what you actually do with fstp is storing a single-precision value. Try fstpl and it will store a double-precision value.

The fixed code should look something like this:

.data
        fl:     .float 12.412
        test:   .string "Result: %f\n"

.text
.global main

main:
        subl $8, %esp
        fld fl
        fstps (%esp)
        flds (%esp)

        fstpl (%esp)        # This line is the only one that has been changed.
        pushl $test
        call printf

        movl $1, %eax
        int $0x80
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top