Search code examples
assemblyx86floating-point32-bitgnu-assembler

properly display float with printf in assembly


this program meant to add 2 float nums and display their respective results but program gives unwanted results and i dont understand why is it necessary to allocate 16 bytes for a float rather as a double occupies 8 bytes so why not allocate only 8 bytes for float?

    .text
    .globl  main
    .type   main, @function
main:
    subl    $12,    %esp    # allocate enough memory for a floating point value
    flds    (V0)        # load loading single precision variable 1
    flds    (V1)        # load single precision variable 2
    fadd    %st(1), %st(0)      # add both of them [ NOTE: reg ST(0) contains correct result ]
    fstpl   (%esp)      # store the float
    pushl   $.LC0
    call    printf
    addl    $16,    %esp    # return allocated mem to OS [ 12 + 4 = 16 ]
    ret

.LC0:   .string "%f\n"

V0: .float 9.3
V1: .float 9.4

Solution

  • Looks buggy to me; ESP is 16-byte aligned before the call to main (which pushes a 4-byte return address), so it should be using sub $12, %esp to recreate 16-byte alignment as required by the i386 System V ABI (assuming you're on Linux) before the call to printf.

    That's what you'd see if you compiled a C function with a C compiler.

    I'd also recommend using flds for the single-precision loads and fstpl for the double-precision store, to make the sizes explicit. This is also buggy; the default is the same for load and store, and this program needs float load and double store. (The default is single-precision float, dword)

    (printf "%f" takes a double because there's no way of passing a float in C to a variadic function: the default promotions apply.)