48 votes

Étiquettes dans l'assemblage en ligne GCC

Dans mon cours d'expérimentation avec GCC assembly en ligne, j'ai rencontré un nouveau problème qui concerne les labels et inline code.

Considérez les points suivants saut simple:

__asm__
(
    "jmp out;"
    "out:;"
    :
    :
);

Ce n'est rien, à l'exception de sauter à l' out label. En l'état, ce code compile bien. Mais si vous le placez à l'intérieur d'une fonction, puis compiler avec les options d'optimisation, le compilateur se plaint: "Erreur: le symbole" out "est déjà défini".

Ce qui semble se passer, c'est que le compilateur est la répétition de cette assemblée de code à chaque fois qu'il inlines la fonction. Ceci provoque l'étiquette out pour obtenir dupliqué, conduisant à de multiples out labels.

Alors, comment puis-je contourner cela? Est-il vraiment pas possible d'utiliser des étiquettes dans un assembly en ligne? Ce tutoriel sur GCC inline assemblée mentionne que:

Ainsi, vous pouvez faire votre assemblée en RPC, les macros, et dans la ligne C fonctions, donc n'importe qui peut l'utiliser en tant que toute fonction C/macro. Les fonctions Inline ressemblent à des macros très bien, mais sont parfois nettoyant à utiliser. Méfiez-vous que dans tous ces cas, le code sera dupliqué, de sorte que seules les labels locaux(de 1: style) doivent être définies dans l' asm code.

J'ai essayé de trouver plus d'informations à propos de ces "local les étiquettes", mais n'arrive pas à trouver quoi que ce soit concernant assembly en ligne. Il ressemble à ce tutoriel est de dire qu'un label local est un nombre suivi d'une virgule (comme 1:), alors j'ai essayé à l'aide d'une étiquette comme ça. Fait intéressant, le code compilé, mais au moment de l'exécution il simplement déclenché une erreur de Segmentation. Hmm...

Donc, des suggestions, des conseils, des réponses...?

61voto

Matthew Slattery Points 21628

Une déclaration d'un label local est en effet un numéro suivi d'un point-virgule. Mais une référence à un label local a besoin d'un suffixe f ou b, selon que vous souhaitez regarder vers l'avant ou vers l'arrière - dire 1f "désigne le 1: de l'étiquette à l'avant de la direction.

Afin de déclarer l'étiquette 1: est correcte; mais pour y faire référence, vous avez besoin de dire jmp 1f (parce que vous êtes le saut en avant dans ce cas).

41voto

David Wohlferd Points 650

Eh bien, cette question n'est pas tout jeune, mais il existe deux autres solutions intéressantes.

1) Cet exemple utilise %=. %= dans un assembleur modèle est remplacé par un numéro qui est unique à chaque insn dans l'ensemble de la compilation. Ceci est utile pour les étiquettes qui sont mentionnés plus d'une fois dans un insn." Notez que pour utiliser %=, vous (apparemment) doit avoir au moins une entrée (bien que vous avez probablement n'avez pas à l'utiliser).

int a = 3;
asm (
    "test %0\n\t"
    "jnz to_here%=\n\t"
    "jz to_there%=\n\t"
    "to_here%=:\n\t"
    "to_there%=:"
    ::"r" (a));

Ce sorties:

test %eax
jnz to_here14
jz to_there14
to_here14:
to_there14:

Alternativement, vous pouvez utiliser l'asm goto (Ajouté dans la v4.5 je pense). Cela vous permet de passer à c étiquettes au lieu de simplement asm étiquettes:

asm goto ("jmp %l0\n"
 : /* no output */
 : /* no input */
 : /* no clobber */
 : gofurther);

printf("Didn't jump\n");

// c label:
gofurther:
printf("Jumped\n");

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X