2016-09-20 1 views
0

Jungs! Ich habe ein Problem. Wie bekomme ich die Adresse der Klassenmitgliedsfunktion von asm in GCC?Wie bekomme ich die Adresse der Klassenmitgliedsfunktion von asm in GCC?

In VS2012 können wir unter Code tun, um Adresse zu erhalten.

asm {mov eax, offset TEST::foo} 

Aber in GCC?

__asm__ __volatile__(
        "movq offset %1, %%rdi" 
        "movq %%rdi, %0" 
        :"=r"(addr) 
        :"r"(&TEST::foo) 
); 

Er scheiterte ...

Antwort

1

AT & T-Syntax verwendet nicht das offset Schlüsselwort. Und außerdem haben Sie den Compiler aufgefordert, &TEST::foo bereits in ein Register zu setzen.

__asm__ (
       "mov %1, %0" 
       :"=r"(addr) 
       :"r"(&TEST::foo) 
); 

Oder besser:

__asm__ (""    // no instructions 
      :"=r"(addr) 
      :"0"(&TEST::foo) // same register as operand 0 
); 

Oder noch besser: addr = &TEST::foo;https://gcc.gnu.org/wiki/DontUseInlineAsm dafür, denn es hält den Compiler zu wissen, was los ist.

Aber wenn Sie sind inline asm verwenden, stellen Sie sicher, dass Sie den Compiler tun so viel wie Sie können. Verwenden Sie Constraints, um anzugeben, wo Sie die Eingabe haben möchten und wo Sie die Ausgabe belassen haben. Wenn die erste oder letzte Anweisung einer inline-asm-Anweisung eine mov ist, bedeutet das normalerweise, dass Sie es falsch machen. (Siehe tag wiki für einige Links auf Führungen wie GNU C Inline-asm zu schreiben, die nicht saugen


Bugs in Ihrem ursprünglichen. Sie keinen clobber auf RDI erklären haben, so wird der Compiler noch annehmen, dass Sie haben es nicht ändern.

Sie nicht volatile brauchen, wenn der einzige Grund, den Code in der asm-Anweisung auszuführen ist, um die Ausgangsoperanden zu erzeugen, nicht für Nebenwirkungen. volatile Weglassen lässt den Compiler optimize um es herum, und sogar fallen lassen es vollständig, wenn der Ausgang nicht verwendet wird.

Verwandte Themen