rep; nop
?pause
?rep nop
(Sans le point-virgule)?nop
?Après une discussion dans les commentaires de ne autre question , j'ai réalisé que je ne sais pas ce que rep; nop;
Signifie dans l'assemblage x86 (ou x86-64). Et aussi je n'ai pas pu trouver une bonne explication sur le web.
Je sais que rep
est un préfixe qui signifie "répéter l'instruction suivante cx
fois" (ou du moins était, dans l'ancien assemblage x86 16 bits). D'après cela tableau récapitulatif sur Wikipedia , il semble que rep
ne peut être utilisé qu'avec movs
, stos
, cmps
, lods
, scas
(mais cette limitation a peut-être été supprimée sur les nouveaux processeurs). Ainsi, je penserais que rep nop
(Sans point-virgule) répéterait une opération nop
cx
fois.
Cependant, après de nouvelles recherches, je suis devenu encore plus confus. Il semble que rep; nop
Et pause
mappent exactement au même opcode , et pause
a un comportement un peu différent que simplement nop
. Certains ancien courrier de 2005 ont dit des choses différentes:
Avec ces différentes opinions, je ne pouvais pas comprendre le sens correct.
Il est utilisé dans le noyau Linux (sur les deux i386 et x86_64 ), avec ce commentaire: /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
Il est également tilisé dans BeRTOS , avec le même commentaire.
rep; nop
est en effet la même que l'instruction pause
(opcode F390
). Il peut être utilisé pour les assembleurs qui ne prennent pas encore en charge l'instruction pause
. Sur les processeurs précédents, cela ne faisait tout simplement rien, tout comme nop
mais en deux octets. Sur les nouveaux processeurs prenant en charge l'hyperthreading, il est utilisé pour indiquer au processeur que vous exécutez une boucle tournante pour augmenter les performances. De référence d'instructions d'Intel :
Améliore les performances des boucles d'attente d'attente. Lors de l'exécution d'une "boucle d'attente de rotation", un processeur Pentium 4 ou Intel Xeon subit une grave pénalité de performances à la sortie de la boucle car il détecte une violation possible de l'ordre de la mémoire. L'instruction PAUSE indique au processeur que la séquence de code est une boucle d'attente d'attente. Le processeur utilise cette astuce pour éviter la violation de l'ordre de la mémoire dans la plupart des situations, ce qui améliore considérablement les performances du processeur. Pour cette raison, il est recommandé de placer une instruction PAUSE dans toutes les boucles d'attente d'attente.
Les préfixes qui ne s'appliquent pas à une instruction sont ignorés. Cependant, les futurs processeurs peuvent utiliser cette séquence d'octets pour coder une nouvelle instruction. (oui, l'espace d'opcode x86 est si limité qu'ils font des trucs fous comme ça, et oui cela complique les décodeurs.)
Dans ce cas, cela signifie que vous pouvez utiliser pause
dans les boucles de spin sans casser la compatibilité arrière . Les anciens processeurs qui ne connaissent pas pause
le décoderont comme un NOP sans aucun dommage. Sur les nouveaux processeurs, vous bénéficiez d'une économie d'énergie/convivialité HT, et évitant les spéculations erronées dans l'ordre de la mémoire lorsque la mémoire sur laquelle vous tournez change et que vous quittez la boucle de rotation.
Liens vers les manuels d'Intel et des tonnes d'autres bonnes choses sur la page d'informations wiki de la balise x86: https://stackoverflow.com/tags/x86/info
Un autre cas où un préfixe rep
vide de sens devient une nouvelle instruction sur les nouveaux processeurs: lzcnt
est F3 0F BD /r
. Sur les processeurs qui ne prennent pas en charge cette instruction (il manque l'indicateur de fonctionnalité LZCNT dans leur CPUID), il décode comme rep bsr
, qui fonctionne de la même manière que bsr
. Ainsi, sur les anciens processeurs, il produit 32 - expected_result
, et n'est pas défini lorsque l'entrée était nulle.
Un cas d'un préfixe rep
vide de sens qui ne décodera probablement jamais différemment: rep ret
est utilisé par défaut par gcc lors du ciblage de CPU "génériques" (c'est-à-dire sans cibler un CPU spécifique avec -march
ou -mtune
, et sans viser AMD K8 ou K10.) Il faudra des décennies avant que quiconque puisse créer un processeur qui décode rep ret
comme autre chose que ret
, car il est présent dans la plupart des binaires de la plupart des distributions Linux. Voir Que signifie "rep ret"?