GCC内联汇编错误:无法获取'this'的地址,这是一个rvalue表达式

时间:2011-06-03 06:44:32

标签: c++ xcode gcc assembly inline-assembly

我仍在与 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 实例的指针?

3 个答案:

答案 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解决方案)来处理问题。