如果我通过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
标记为已破坏,因为在内联汇编程序中已经使用了eax
和edx
。
对于x86-64,文档为here,并说
关于c++ - GNU内联汇编:哪些寄存器被__stdcall破坏?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17932423/