如果我通过C++代码中的GNU内联汇编器使用call指令来调用一个我知道的函数,则使用__stdcall约定,我是否必须列出所有寄存器?

我在互联网上找不到很好的指导,但是%eax%edx%ecx看起来像是调用者保存的,前两个保留用于返回值。

这是我的代码。我想知道在第三个冒号之后需要放置的内容。

#include <cstdint>

namespace {

inline uint64_t invoke_stdcall(uint64_t (* stdcall_func)())
{
    unsigned long hi32, lo32;
    asm(
        "call %2"
        : "=d" (hi32), "=a" (lo32)
        : "m" (stdcall_func)
        : /* HELP! What goes here? */
    );
    return static_cast<uint64_t>(hi32) << 32 | static_cast<uint32_t>(lo32);
}

} // anonymous namespace

This message thread是我在互联网上可以找到的最好的,但是我一直找不到能说“这就是__stdcall假定它可以不保存就可以修改”的内容。

最佳答案

MS确实解释了EAX,EDX和ECX被调用“破坏”了,所有其他寄存器必须由被调用方以32位代码link to MSDN docs保留-不管使用哪种调用约定。

因此,很明显,您需要将ecx标记为已破坏,因为在内联汇编程序中已经使用了eaxedx

对于x86-64,文档为here,并说

关于c++ - GNU内联汇编:哪些寄存器被__stdcall破坏?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17932423/

10-12 02:24