2011-06-03 13 views
6

Todavía estoy luchando con GCC - compilar el siguiente código ensamblador en línea (con -fasm-bloques, lo que permite Intel estilo sintaxis de montaje) me redes de un error extraño no se puede tomar la dirección de 'esto', que es una expresión rvalue ...GCC error de montaje en línea: No se puede tomar la dirección de 'esto', que es una expresión 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 
     //... 
    }; 
} 


¿por qué puedo almacenar punteros a objetos diferentes en los registros, pero no puede usar puntero a instancia de MyClass?

+0

Sólo una idea de último momento, ¿qué pasa con 'lea ebx, [this]'? – Xeo

Respuesta

1

Eso es porque el compilador puede decidir por sí mismo para almacenar this en un registro (generalmente ECX) en lugar de una celda de memoria, con fines de optimización, o porque el calling convention especifica explícitamente que debería hacer eso.

En ese caso, usted no puede tomar su dirección, ya que los registros no son de memoria direccionable.

+1

En realidad, resolví el problema creando un puntero local MyClass * p = this y parece estar funcionando ... – Ryan

1

se puede usar algo como esto:

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

Ver más detalles sobre operandos que pasan a asm en línea here

+0

Gracias, pero ¿estás seguro de que no hay otra manera? – Ryan

0

En términos prácticos, cada implementación define sus propias reglas con respecto a asm. En el caso de g ++, parece que cuando se escribe mov ebx, something, g ++ necesita la dirección de something con el fin de generar la instrucción. (No es sorprendente, realmente, dado el funcionamiento de los ensambladores ). this no tiene una dirección. (Eso es lo que significa un valor r). La implementación podría tratar this como un caso especial en ensamblador en línea, y reemplazarlo con lo que sea apropiado en que se encuentre en el código. g ++ no hace esto, probablemente porque tiene otro mecanismo más general (la solución de elder_george) que maneja el problema.

Cuestiones relacionadas