开发者

Why is this simple program outputting so many characters?

开发者 https://www.devze.com 2023-01-16 07:12 出处:网络
Here is my short assem开发者_开发技巧bly program: ; This code has been generated by the 7Basic ; compiler <http://launchpad.net/7basic>

Here is my short assem开发者_开发技巧bly program:

; 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

What the program is supposed to do is print 5.5, but it prints:

-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000

What on earth am I doing wrong? The code is pushing the two arguments to printf() and then calling it. Nothing complicated.


Update: I was a little premature in thinking I had fixed this. I have updated the code.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消