【问题标题】:Compiler ignore __stdcall编译器忽略 __stdcall
【发布时间】:2012-08-06 18:34:32
【问题描述】:

在我看来,MSVS 忽略了我函数上的 __stdcall 指令。我正在手动清理堆栈,但编译器仍会在每个 CALL 之后附加 ADD ESP 指令。

这是我声明函数的方式:

extern "C" void * __stdcall core_call(int addr, ...);
#define function(...) (DWORD WINAPI) core_call(12345, __VA_ARGS__)
return function("Hello", 789);

这是输出的样子:
(来源:server4u.cz

我用箭头标记了多余的 ADD 指令,MSVS 会在每次调用后自动附加,尽管事实上清理堆栈是被调用者的责任(参考:http://en.wikipedia.org/wiki/X86_calling_conventions#List_of_x86_calling_conventions),这会导致我的程序崩溃.如果我用NOPs 手动替换ADD 指令,程序将按预期工作。所以,我的问题是......有没有办法强制编译器停止添加这些指令?

谢谢。

【问题讨论】:

    标签: c++ visual-c++ calling-convention


    【解决方案1】:

    问题出在这里:, ...)

    参数数量可变的函数不能是__stdcall

    __stdcall 函数必须在最后从堆栈中删除所有堆栈参数,但它们无法提前知道将接收多少作为参数的东西。

    __fastcall 函数也是如此。

    对于参数数量可变的函数,唯一适用的调用约定是__cdecl,其中调用者必须在调用后删除堆栈参数。尽管您要求使用__stdcall,这就是编译器使用的内容。

    【讨论】:

    • 你知道编译器忽略显式请求的调用约定是否会产生警告吗?
    • 感谢您的回复。当我发现问题出在哪里时,我花了几个小时调试代码。编译器显示了一些警告,但我不太清楚为什么它忽略了我明确分配的内容。但是,是否有一些解决方法可以做到这一点?我什至尝试编写一些内联程序集来将参数传递给函数 core_call,但我没有成功。
    • 经过几个小时的调试,我终于找到了适用于 MSVS 的解决方案。这有点讨厌,但它确实有效。 pastebin.com/QmUQKm9S
    猜你喜欢
    • 2013-09-10
    • 2014-07-19
    • 2019-05-22
    • 1970-01-01
    • 2012-08-17
    • 2010-09-11
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多