web-dev-qa-db-fra.com

Pourquoi les instructions x86-64 sur les registres 32 bits mettent-elles à zéro la partie supérieure du registre 64 bits complet?

Dans le x86-64 Tour of Intel Manuals , je lis

Le fait peut-être le plus surprenant est qu'une instruction telle que MOV EAX, EBX met à zéro automatiquement les 32 bits supérieurs du registre RAX.

La documentation Intel (3.4.1.1 Registres à usage général en mode 64 bits dans l'architecture de base manuelle) citée à la même source nous dit:

  • Les opérandes 64 bits génèrent un résultat 64 bits dans le registre à usage général de destination.
  • Les opérandes 32 bits génèrent un résultat 32 bits, étendu de zéro à un résultat 64 bits dans le registre à usage général de destination.
  • Les opérandes 8 bits et 16 bits génèrent un résultat 8 bits ou 16 bits. Les 56 bits ou 48 bits supérieurs (respectivement) du registre à usage général de destination ne sont pas modifiés par l'opération. Si le résultat d'une opération 8 bits ou 16 bits est destiné au calcul d'adresse 64 bits, signez explicitement l'extension du registre aux 64 bits complets.

Dans l'assemblage x86-32 et x86-64, des instructions 16 bits telles que

mov ax, bx

ne montre pas ce genre de comportement "étrange" que le mot supérieur d'eax est mis à zéro.

Ainsi: quelle est la raison pour laquelle ce comportement a été introduit? À première vue, cela semble illogique (mais la raison pourrait être que je suis habitué aux caprices de l'assemblage x86-32).

94
Nubok

Je ne suis pas AMD ou je ne parle pas pour eux, mais je l'aurais fait de la même manière. Parce que la remise à zéro de la moitié supérieure ne crée pas de dépendance à la valeur précédente, le processeur devrait attendre. Le mécanisme de changement de nom de registre serait essentiellement vaincu s'il n'était pas fait de cette façon. De cette façon, vous pouvez écrire du code 32 bits rapide en mode 64 bits sans avoir à rompre explicitement les dépendances tout le temps. Sans ce comportement, chaque instruction 32 bits unique en mode 64 bits devrait attendre quelque chose qui s'est passé avant, même si cette partie élevée ne serait presque jamais utilisée.

Le comportement des instructions 16 bits est étrange. La folie de la dépendance est l'une des raisons pour lesquelles les instructions 16 bits sont désormais évitées.

79
harold

Il économise simplement de l'espace dans les instructions et le jeu d'instructions. Vous pouvez déplacer de petites valeurs immédiates vers un registre 64 bits à l'aide d'instructions existantes (32 bits).

Cela vous évite également d'avoir à coder des valeurs de 8 octets pour MOV RAX, 42, quand MOV EAX, 42 peut être réutilisé.

Cette optimisation n'est pas aussi importante pour les opérations 8 et 16 bits (car elles sont plus petites), et changer les règles là-bas casserait également l'ancien code.

9
Bo Persson