7
votes

Qu'est-ce que r () et double pour cent %% dans la langue de montage en ligne de GCC?

Exemple:

int main(void)
{
    int x = 10, y;

    asm ("movl %1, %%eax;"
        "movl %%eax, %0;"
        :"=r"(y)    /* y is output operand */
        :"r"(x)     /* x is input operand */
        :"%eax");   /* %eax is clobbered register */
}
  • Qu'est-ce que r (y) code>? li>
  • aussi pourquoi %% code> est utilisé avant EAX code>? Généralement célibataire % code> est utilisé droit? li> ul> p>


3 commentaires

Aussi je n'ai pas eu ce que = r (y) et r (x)? aussi ce qui est un registre clobbered?


Double pourcentage sous-mère: Stackoverflow.com/Questtions/14745631/...


Méfiez-vous de l'ASM de base VS étendu: Stackoverflow.com/a/31711138/895245


4 Réponses :


0
votes

Je ne peux pas répondre à tout cela, mais un registre encombré est celui qui sera utilisé quelque part dans le calcul de manière à détruire sa valeur actuelle. Donc, si l'appelant souhaite utiliser la valeur actuelle plus tard, il doit l'enregistrer d'une manière ou d'une autre.

dans ASM Directives telles que ceci, lorsque vous écrivez l'assemblage, vous déterminez quels registres vont être encombrés par celui-ci; Vous indiquez ensuite au compilateur ceci (comme indiqué dans votre exemple), et le compilateur fait ce qu'il doit faire pour préserver la valeur actuelle de ce registre si nécessaire. Le compilateur sait beaucoup sur la manière dont les valeurs des registres et ailleurs seront utilisées pour des calculs ultérieurs, mais il ne peut généralement pas analyser l'assemblage incorporé. Donc, vous faites l'analyse vous-même et le compilateur utilise les informations sur les clocables pour intégrer en toute sécurité l'Assemblée dans ses choix d'optimisation.


0 commentaires


9
votes

D'accord, il s'agit d'un assembleur en ligne GCC qui très puissant mais difficile à comprendre.

Tout d'abord, le% de caractère est un caractère spécial. Cela vous permet de définir les espaces réservés et numéros (mor à cela plus tard). Malheureusement, le% est également utilisé comme faisant partie d'un nom de registre (tel que% EAX), donc dans l'assembleur en ligne GCC, vous devez utiliser deux pour cent caractères si vous souhaitez nommer un registre.

% 0,% 1 et% 2 (ect ..) sont des opérandes d'entrée et de sortie d'espace réservé. Ceux-ci sont définis dans la liste suivie de la chaîne d'assembleur. Dans votre exemple% 0 devient un espace réservé pour y, et% 1 devient un espace réservé pour x. Le compilateur s'assurera que les variables seront dans les registres des opérandes d'entrée avant l'exécution du code ASM et s'assurera que l'opérande de sortie sera écrit à la variable spécifiée dans la liste des opérations de sortie.

Maintenant, vous devez avoir une idée de ce que R (Y) est: c'est un opérande d'entrée qui se réserve un registre de la variable Y et l'attribue à l'espace réservé 1 (car il s'agit du second opérande répertorié après la chaîne d'assembleur en ligne. ). Il y a beaucoup d'autres types d'espace réservés. m vous permet de spécifier un emplacement de mémoire, et si je ne me trompe pas, je peux être utilisé pour les constantes numériques. Vous les trouverez tous répertoriés dans la documentation GCC.

Il y a la liste des clobs. Cette liste est importante! Il répertorie toutes les registres, les drapeaux, les emplacements Memory-ECT qui sont modifiés dans votre code d'assembleur (tel que l'EAX de votre exemple). Si vous avez mal, l'optimiseur pas savoir ce qui a été modifié et il est très probable que vous finissez avec du code qui ne fonctionne pas.

Votre exemple est à la manière presque inutile. Il charge simplement la valeur x dans un registre et attribue ce registre à EAX. Ensuite, EAX est stocké dans un autre registre qui deviendra ensuite votre variable y. Donc, tout ce qu'il fait est une simple affectation:

y = x;

Une dernière chose: si vous avez déjà travaillé avec un assembleur de style Intel avant: vous devez lire les arguments à l'envers. Pour toutes les instructions, l'opérande source est celui qui suit l'instruction elle-même et l'opérande cible est celui à la droite de la virgule. Par rapport à la syntaxe Intel, c'est exactement l'inverse.


0 commentaires

1
votes

Les lignes avec "R" ou "= r" sont des contraintes d'opérande. Le "=" signifie opérande de sortie. Essentiellement, ceci: xxx

signifie que% 0 (c'est-à-dire: le premier opérande) correspond à Y et est pour la sortie, et% 1 (le deuxième opérande) correspond à x.

Un seul% est normalement utilisé dans l'ensemble Syntaxe AT & T, mais pour l'assemblage en ligne, le seul% est utilisé pour les références d'opérande (par exemple:% 0,% 1), tandis qu'un double% est utilisé pour les références de registre littéral. Pensez-y comme si vous devez utiliser un double% dans un format PrintF si vous souhaitez un% littéral dans la sortie.

Un registre clavégié est un registre dont la valeur sera modifiée par le code de montage. Comme vous pouvez le constater à partir du code, EAX est écrit à. Vous devez dire à GCC à ce sujet afin qu'il sache que le code compilé ne peut pas garder quelque chose dont il a besoin plus tard dans EAX lorsqu'il est sur le point d'invoquer cet assemblage.


0 commentaires