我如何在 GCC 中通过 asm 获取 class 成员函数的地址?
How do I get address of class member function by asm in GCC?
伙计们!我有个问题。我如何在 GCC 中通过 asm 获取 class 成员函数的地址?
在VS2012中,我们可以通过下面的代码获取地址。
asm {mov eax, offset TEST::foo}
但是,在 GCC 中?
__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 因为它阻止编译器知道发生了什么。
但是如果您打算使用内联汇编,请确保让编译器尽可能多地为您做。使用约束来告诉它你想要输入的位置,以及你离开输出的位置。如果 inline-asm 语句的第一条或最后一条指令是 mov
,通常这意味着你做错了。 (请参阅 inline-assembly tag wiki 以获取有关如何编写不差劲的 GNU C 内联汇编的指南链接。
你原来的错误:你没有在 RDI 上声明一个 clobber,所以编译器仍然会假设你没有修改它。
如果 运行 asm 语句中的代码的唯一原因是产生输出操作数,而不是为了副作用,则不需要 volatile
。省略 volatile
可以让编译器围绕它进行优化,如果输出未使用,甚至可以完全删除它。
伙计们!我有个问题。我如何在 GCC 中通过 asm 获取 class 成员函数的地址?
在VS2012中,我们可以通过下面的代码获取地址。
asm {mov eax, offset TEST::foo}
但是,在 GCC 中?
__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 因为它阻止编译器知道发生了什么。
但是如果您打算使用内联汇编,请确保让编译器尽可能多地为您做。使用约束来告诉它你想要输入的位置,以及你离开输出的位置。如果 inline-asm 语句的第一条或最后一条指令是 mov
,通常这意味着你做错了。 (请参阅 inline-assembly tag wiki 以获取有关如何编写不差劲的 GNU C 内联汇编的指南链接。
你原来的错误:你没有在 RDI 上声明一个 clobber,所以编译器仍然会假设你没有修改它。
如果 运行 asm 语句中的代码的唯一原因是产生输出操作数,而不是为了副作用,则不需要 volatile
。省略 volatile
可以让编译器围绕它进行优化,如果输出未使用,甚至可以完全删除它。