我仍在与 GCC 作斗争 - 编译以下内联汇编代码(使用 -fasm-blocks ,启用 Intel样式程序集语法)给我一个奇怪的错误不能取'this'的地址,这是一个右值表达式 ......
MyClass::MyFunction()
{
_asm
{
//...
mov ebx, this // error: Cannot take the address of 'this', which is an rvalue expression
//...
mov eax, this // error: Cannot take the address of 'this', which is an rvalue expression
//...
};
}
为什么我可以将指针存储到寄存器中的不同对象,但是不能使用指向 MyClass 实例的指针?
答案 0 :(得分:1)
这是因为编译器可能自己决定将this
存储在寄存器(通常为ECX
)而不是存储器单元中,以用于优化目的,或者因为{{3明确指出它应该这样做。
在这种情况下,你不能取其地址,因为寄存器不是可寻址的存储器。
答案 1 :(得分:1)
您可以使用以下内容:
#include <stdio.h>
class A{
public:
void* work(){
void* result;
asm( "mov %%eax, %%eax"
: "=a" (result) /* put contents of EAX to result*/
: "a"(this) /* put this to EAX */
);
return result;
}
};
int main(){
A a;
printf("%x - %x\n", &a, a.work());
}
查看有关传递给内联asm here
的操作数的更多详细信息答案 2 :(得分:0)
实际上,每个实现都定义了自己的规则
对于asm。对于g ++,看起来就像写mov
ebx, something
时,g ++需要something
的地址才能
生成指令。 (不要惊讶,真的,顺便说一句
汇编工作。)this
没有地址。 (那是什么
右值意味着。)实施可以将this
视为特殊
内联汇编程序中的case,并用适当的东西替换它
代码中的那个位置。 g ++不会这样做,可能是因为它有
另一个更通用的机制(elder_george解决方案)来处理问题。