2016-09-20 1 views
0

les gars! J'ai un problème. Comment puis-je obtenir l'adresse du membre du groupe par asm dans GCC?Comment obtenir l'adresse de la fonction de membre de classe par asm dans GCC?

Dans VS2012, nous pouvons faire ci-dessous le code pour obtenir l'adresse.

asm {mov eax, offset TEST::foo} 

Mais, dans GCC?

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

Il a échoué ...

Répondre

1

AT & T syntaxe n'utilise pas le mot-clé offset. Et d'ailleurs, vous avez demandé au compilateur de mettre déjà &TEST::foo dans un registre.

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

Ou mieux:

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

Ou encore mieux: addr = &TEST::foo;https://gcc.gnu.org/wiki/DontUseInlineAsm pour cela, car il empêche le compilateur de savoir ce qui se passe.

Mais si vous êtes va utiliser inline asm, assurez-vous de laisser le compilateur faire autant pour vous que possible. Utilisez des contraintes pour lui dire où vous voulez l'entrée, et où vous avez quitté la sortie. Si la première ou la dernière instruction d'une instruction inline-asm est mov, cela signifie généralement que vous vous trompez. (Voir la tag wiki quelques liens vers des guides sur la façon d'écrire GNU C asm en ligne qui ne sucent pas


Bugs dans l'original. Vous n'avez pas fait un clobber sur RDI, de sorte que le compilateur on suppose encore que vous ne l'avez pas le modifier.

vous n'avez pas besoin volatile si la seule raison pour exécuter le code dans l'instruction asm est de produire les opérandes de sortie, pas pour les effets secondaires. Laissant volatile permet à l'optimize du compilateur autour de lui, et même le laisser tomber entièrement si la sortie est inutilisée