¿Por qué es este sencillo programa dando salida a tantos personajes?
Pregunta
Aquí está mi resumen Montaje de programa:
; This code has been generated by the 7Basic
; compiler <http://launchpad.net/7basic>
extern printf
; Initialized data
SECTION .data
f_0 dd 5.5
printf_f: db "%f",10,0
SECTION .text
; Code
global main
main:
push ebp
mov ebp,esp
push dword [f_0]
push printf_f
call printf
add esp,8
mov esp,ebp
pop ebp
mov eax,0
ret
¿Qué es el programa supuesta ??em> que hacer es imprimir 5.5, pero se imprime:
-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000
¿Qué diablos estoy haciendo mal? El código está empujando los dos argumentos a printf()
y luego llamarlo. Nada complicado.
Actualización: que era un poco prematuro al pensar que había fijado esto. He actualizado el código.
Solución
The instruction push f_0
pushes the address of f_0 on the stack, not the 5.5 in memory there, so the printf routine will take the address, plus the saved ebp (the next 4 bytes on the stack) and interpret the bits as a double and print it out. That turns out to be a very large number, as you see.
You need to load 8 bytes from f_0
and push those. something like
move eax, f_0
push dword ptr [eax+4]
push dword ptr [eax]
edit
You need to push 8 bytes as fp64 values are 8 bytes. fp64 is all that printf knows how to print -- in fact fp64 is all that C knows how to pass to functions or operate on. fp32 value can only be loaded from and stored to memory, but are always implicitly converted to fp64 (or larger) before being operated on. If you want to load an fp32 value, convert it fp64, and push it on the stack, you can use
fld dword ptr [f_0]
sub esp, 8
fstp qword ptr [esp]
This actually loads an fp32 value and converts it to fp80 (the x87's internal format), then converts that fp80 value to fp64 and stores it on the stack.