【发布时间】:2013-06-14 16:25:29
【问题描述】:
我正在尝试使用 vs2008 将程序移植到 x64。然而,问题在于,这是一些 x64 不支持的内联 asm 代码。此 asm 代码用于将具有未知类型或编号的参数从 dll 推送到函数。它是一个基于 interpeter 的程序,您可以在其中指定要从某个 dll 使用的函数,程序会推送参数并在编译时调用该函数。
使用各种来源,我得出的结论是生成单独的 .asm 文件,其中包含 asm 函数,这些函数可以编译为 unsing masm 及其链接到 vs2008 的 obj 文件。为 x86 和 x64 使用不同的文件,程序为这两个问题构建。然而问题是,这些函数并没有复制内联汇编正在做的事情。
我转换了以下内联代码,例如:
double a = Evaluate(arg[i]).num;
_asm push a + 4
_asm push a
j += 8;
收件人:
double a = Evaluate(arg[i]).num;
EvaluateFuncArgFloat(a);
j += 8;
使用以下 .asm 文件:
TITLE EvaluateFuncArgFloat (evaluate_asm.asm)
.386
.model flat, C
.code
EvaluateFuncArgFloat PROC a:DWORD
push a + 4
push a
ret
EvaluateFuncArgFloat ENDP
END
这并没有达到我的预期。 double 根本不会像使用内联 asm 时那样在函数中结束。
我的猜测是有一个小错误或我遗漏了一些东西,但经过多次尝试后,我似乎无法让它工作。希望有人能帮我解决这个问题,非常感谢。
【问题讨论】:
-
调用函数的语义不能与内联程序集相同...涉及函数调用,这将修改堆栈。
-
这段代码之后会发生什么?在 x86-64 上,函数参数可能会在寄存器中而不是在堆栈中找到。
-
感谢你们的帮助。 Michael:在这段代码之后,它使用解释的名称和以下声明调用函数:double (*func_d)(void);
-
你没有把你的堆栈搞得一团糟吗?两次推送和一次 ret 意味着它会返回到第二次推送
-
@user2486757:哦,你还在使用 32 位代码。好吧,要让您的汇编函数返回到正确的位置,您可以尝试将其更改为:
pop eax/push dword ptr [a+4]/push dword ptr [a]/push eax/ret。
标签: visual-c++ assembly 64-bit push inline-assembly