为什么这个简单的程序会输出这么多字符?
Here is my short assembly 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做错了吗?该代码将两个参数推送到 printf()
,然后调用它。没什么复杂的。
更新:我认为我已经解决了这个问题有点过早。我已经更新了代码。
Here is my short assembly 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
指令
push f_0
将 f_0 的地址压入堆栈,而不是内存中的 5.5,因此 printf 例程将获取该地址,加上保存的 ebp(堆栈上接下来的 4 个字节)和将这些位解释为双精度并将其打印出来。正如您所看到的,结果是一个非常大的数字。您需要从
f_0
加载 8 个字节并推送它们。类似于edit
您需要推送 8 个字节,因为 fp64 值是 8 个字节。 fp64 是 printf 知道如何打印的所有内容——事实上,fp64 是 C 知道如何传递给函数或进行操作的所有内容。 fp32 值只能从内存加载和存储到内存,但在操作之前始终隐式转换为 fp64(或更大)。如果你想加载一个fp32值,将其转换为fp64,并将其压入堆栈,你可以使用
这实际上加载了一个fp32值并将其转换为fp80(x87的内部格式),然后将该fp80值转换为fp64并存储它在堆栈上。
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 likeedit
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
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.