Ошибка встроенной сборки GCC: невозможно получить адрес «this», который является выражением rvalue - PullRequest
6 голосов
/ 03 июня 2011

Я все еще борюсь с GCC - компилируя следующий встроенный код сборки (с -fasm-blocks , который включает Intel style синтаксис сборки) сетимне странная ошибка Не могу взять адрес 'this', который является rvalue выражением ...

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 ]

1 голос
/ 03 июня 2011

Вы можете использовать что-то вроде этого:

#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 здесь

1 голос
/ 03 июня 2011

Это потому, что компилятор может решить самостоятельно хранить this в регистре (обычно ECX) вместо ячейки памяти, в целях оптимизации, или потому что соглашение о вызовах явно указывает его должен сделать это.

В этом случае вы не можете получить его адрес, потому что регистры не являются адресуемой памятью.

0 голосов
/ 03 июня 2011

Практически каждая реализация определяет свои собственные правила с привет асм. В случае g ++ это выглядит так, как будто вы пишете mov ebx, something, g ++ нужен адрес something, чтобы сгенерировать инструкцию. (Не удивительно, на самом деле, учитывая способ ассемблеры работают.) this не имеет адреса. (Это то, что существо rvalue означает.) Реализация может рассматривать this как особый в встроенном ассемблере и замените его на любой это место в коде. g ++ не делает этого, вероятно потому что другой, более общий механизм (решение elder_george), который обрабатывает проблему.

...