GCC build assembly error: cannot get address 'this', which is an rvalue expression

I am still struggling with GCC - compiling the following built-in assembler code (with -fasm-blocks , which allows you to compile Intel style syntax) disables a strange error for me. Unable to accept the address 'this', which is an rvalue expression ...

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 registries, but cannot use a pointer to an instance of MyClass ?

+6
source share
3 answers

This is because the compiler may decide to save this in a register (usually ECX ) instead of a memory location for optimization purposes, or because the calling convention explicitly indicates that it should do this.

In this case, you cannot accept your address, because the registers are not address memory.

+1
source

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

Read more about operands passed inline asm here

+1
source

In practical terms, each implementation defines its own rules using asm. In the case of g ++, it looks like when you write mov ebx, something , g ++ needs the address something to generate the instruction. (Not surprisingly, indeed, given the way the collectors work.) this has no address. (Whatever the value of rvalue.) An implementation may consider this as a special case in inline assembler, and replace it with what is appropriate for this place in the code. g ++ does not do this, probably because it is a different, more general mechanism (old_george solution) that handles the problem.

0
source

Source: https://habr.com/ru/post/889674/


All Articles