Nat*_*man 0 x86 assembly printf x87
这是我的短装配程序:
; 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
Run Code Online (Sandbox Code Playgroud)
该程序应该做的是打印5.5,但它打印:
-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000
我究竟做错了什么?代码将两个参数推送到printf()然后调用它.没什么复杂的.
更新:我认为我修复了这个问题还为时过早.我已经更新了代码.
该指令push f_0在堆栈中推送f_0的地址,而不是内存中的5.5,所以printf例程将获取地址,加上保存的ebp(堆栈中的下4个字节)并将这些位解释为double并打印出来出.如你所见,这是一个非常大的数字.
您需要加载8个字节f_0并推送它们.就像是
move eax, f_0
push dword ptr [eax+4]
push dword ptr [eax]
Run Code Online (Sandbox Code Playgroud)
编辑
您需要按8个字节,因为fp64值是8个字节.fp64就是printf知道如何打印的 - 事实上fp64就是C知道如何传递给函数或进行操作.fp32值只能从内存加载并存储到内存中,但在操作之前总是隐式转换为fp64(或更大).如果要加载fp32值,将其转换为fp64,并将其推入堆栈,即可使用
fld dword ptr [f_0]
sub esp, 8
fstp qword ptr [esp]
Run Code Online (Sandbox Code Playgroud)
这实际上加载了一个fp32值并将其转换为fp80(x87的内部格式),然后将该fp80值转换为fp64并将其存储在堆栈中.
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |