简体   繁体   English

GCC 内联汇编错误:不能取'this'的地址,这是一个右值表达式

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

I'm still fighting with GCC - compiling the following inline assembly code (with -fasm-blocks , which enables Intel style assembly syntax) nets me a strange error Cannot take the address of 'this', which is an rvalue expression ...我仍在与GCC战斗 - 编译以下内联汇编代码(使用-fasm-blocks ,它启用英特尔风格的汇编语法)给我带来了一个奇怪的错误,无法获取“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
        //...
    };
}


Why can I store pointers to different objects in registers, but can't use pointer to MyClass instance?为什么我可以将指向不同对象的指针存储在寄存器中,但不能使用指向MyClass实例的指针?

That's because the compiler might decide on its own to store this in a register (generally ECX ) instead of a memory cell, for optimization purposes, or because the calling convention explicitly specifies it should do that.这是因为编译器可能会自行决定将this存储在寄存器(通常是ECX )而不是 memory 单元中,出于优化目的,或者因为调用约定明确指定它应该这样做。

In that case, you cannot take its address, because registers are not addressable memory.在这种情况下,您无法获取其地址,因为寄存器不可寻址 memory。

You can use something like this:你可以使用这样的东西:

#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());
}

See more details on operands passing to inline asm here此处查看有关传递给内联 asm 的操作数的更多详细信息

Practically speaking, each implementation defines its own rules with regards to asm.实际上,每个实现都定义了自己的关于 asm 的规则。 In the case of g++, it looks like when you write mov ebx, something , g++ needs the address of something in order to generate the instruction.在 g++ 的情况下,看起来当您编写mov ebx, something时,g++ 需要something的地址才能生成指令。 (Not to surprising, really, given the way assemblers work.) this doesn't have an address. (实际上,考虑到汇编器的工作方式, this并不奇怪。)它没有地址。 (That's what being an rvalue means.) The implementation could treat this as a special case in inline assembler, and replace it with whatever is appropriate at that spot in the code. (这就是右值的含义。)实现可以将this视为内联汇编程序中的一种特殊情况,并将其替换为代码中该位置适当的任何内容。 g++ doesn't do this, probably because it has another, more general mechanism (elder_george's solution) which handles the problem. g++ 没有这样做,可能是因为它有另一个更通用的机制(elder_george 的解决方案)来处理这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM