GCC 内联程序集错误:无法获取"this"的地址,这是一个右值表达式

GCC inline assembly error: Cannot take the address of 'this', which is an rvalue expression

本文关键字:表达式 一个 错误 程序集 GCC this 获取 地址      更新时间:2023-10-16

我仍在与GCC作斗争-编译以下内联汇编代码(使用-fasm块,它启用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实例的指针?

这是因为出于优化目的,编译器可能会自行决定将this存储在寄存器(通常为ECX)中,而不是存储单元中,或者因为调用约定明确指定它应该这样做。

在这种情况下,您不能获取它的地址,因为寄存器不是可寻址的内存。

您可以使用这样的东西:

#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 - %xn", &a, a.work());
}

请在此处查看传递到内联asm的操作数的更多详细信息

实际上,每个实现都定义了自己的规则关于asm。在g++的情况下,当您编写mov ebx, something时,g++需要something的地址才能生成指令。(顺便说一句,真的不足为奇装配工工作。)this没有地址。(这就是右值的意思。)该实现可以将this视为一个特殊的内联汇编程序中的case,并将其替换为代码中的那个位置。g++不这么做,可能是因为它另一个更通用的机制(eldergeorge的解决方案)来处理这个问题。

相关文章: