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.
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