这是我的 短的 装配程序:

; 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

该程序是什么 应该 要做的是打印5.5,但它打印:

-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000

我到底做错了什么?该代码将两个参数推向 printf() 然后打电话。没什么复杂的。


更新: 我以为我已经修复了这一点还为时过早。我已经更新了代码。

有帮助吗?

解决方案

指令 push f_0 按堆栈上的F_0的地址,而不是其中的内存中的5.5,因此PrintF例程将采用该地址,再加上保存的EBP(堆栈上的下4个字节),并将其解释为双重并将其打印出来。如您所见,事实证明这是一个非常大的数字。

您需要从中加载8个字节 f_0 并推。就像是

move eax, f_0
push dword ptr [eax+4]
push dword ptr [eax]

编辑

您需要按8个字节,因为fp64值为8个字节。 FP64就是printf知道如何打印的一切 - 实际上,FP64就是C知道如何传递到功能或操作。 FP32值只能从并存储到内存,但在操作之前始终将其隐式转换为FP64(或更大)。如果要加载fp32值,请将其转换为fp64,然后将其推在堆栈上,可以使用

fld dword ptr [f_0]
sub esp, 8
fstp qword ptr [esp]

实际上,这加载了FP32值并将其转换为FP80(X87的内部格式),然后将FP80值转换为FP64并将其存储在堆栈中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top