伙计们!我有个问题。如何通过GCC中的asm获取类成员函数的地址?
在VS2012中,我们可以执行以下代码来获取地址。
asm {mov eax, offset TEST::foo}
但是,在海湾合作委员会?
__asm__ __volatile__(
"movq offset %1, %%rdi"
"movq %%rdi, %0"
:"=r"(addr)
:"r"(&TEST::foo)
);
它失败了。。。
AT&T语法不使用offset
关键字。此外,您已经要求编译器将&TEST::foo
放入寄存器中。
__asm__ (
"mov %1, %0"
:"=r"(addr)
:"r"(&TEST::foo)
);
或者更好:
__asm__ ( "" // no instructions
:"=r"(addr)
:"0"(&TEST::foo) // same register as operand 0
);
甚至更好:addr = &TEST::foo;
https://gcc.gnu.org/wiki/DontUseInlineAsm因为它阻止编译器知道发生了什么。
但是,如果要使用内联asm,请确保让编译器尽可能多地为您服务。使用约束来告诉它输入的位置和输出的位置。如果内联asm语句的第一条或最后一条指令是mov
,通常意味着您做得不对。(有关如何编写GNUC内联asm的一些链接,请参阅内联汇编标记wiki
你原来的错误:你没有在RDI上声明一个clobber,所以编译器仍然会认为你没有修改它。
如果在asm语句中运行代码的唯一原因是生成输出操作数,而不是为了产生副作用,则不需要volatile
。省略volatile
可以让编译器围绕它进行优化,如果输出未使用,甚至可以完全删除它。