2012-06-24 12 views
68

Vom x86-64 Tour of Intel Manuals las ichWarum zerlegen x86-64-Anweisungen in 32-Bit-Registern den oberen Teil des vollständigen 64-Bit-Registers?

Vielleicht ist die überraschende Tatsache ist, dass eine Anweisung wie MOV EAX, EBX automatisch oberen 32 Bits von RAX Register Nullen.

Die Intel-Dokumentation (3.4.1.1 Allzweckregister in 64-Bit-Modus in der manuellen Grund Architecture) an der gleichen Quelle zitiert sagt uns:

  • 64-Bit-Operanden erzeugen eine 64 -Bit führt zum Ziel-Allzweckregister.
  • 32-Bit-Operanden erzeugen ein 32-Bit-Ergebnis, das im Ziel-Allzweckregister zu einem 64-Bit-Ergebnis Null erweitert wird.
  • 8-Bit- und 16-Bit-Operanden erzeugen ein 8-Bit- oder 16-Bit-Ergebnis. Die oberen 56 Bits bzw. 48 Bits des Ziel-Allzweckregisters werden nicht durch die Operation modifiziert. Wenn das Ergebnis einer 8-Bit- oder 16-Bit-Operation für die 64-Bit-Adressberechnung bestimmt ist, zeichen Sie das Register explizit auf die vollen 64 Bits aus.

In x86-32 und x86-64 Montag, 16-Bit-Befehle wie

mov ax, bx 

zeigen nicht diese Art von "fremdem" Verhalten, dass das obere Wort von EAX auf Null gesetzt wird.

Also: Was ist der Grund, warum dieses Verhalten eingeführt wurde? Auf den ersten Blick scheint es unlogisch (aber der Grund könnte sein, dass ich an die Macken der x86-32 Versammlung gewöhnt bin).

+11

Wenn Sie Google für "Partial Register Stall", finden Sie eine ganze Reihe von Informationen über das Problem, das sie (fast sicher) versucht zu vermeiden. –

+3

http://stackoverflow.com/questions/25455447/x86-64-register-rax-ax-ax-al-overwriting-ful-register-contents –

+1

Nicht nur "die meisten".AFAIK, * alle * Anweisungen mit einem 'r32'-Zieloperanden setzen das Hoch 32 auf Null, anstatt es zu verschmelzen. Zum Beispiel werden einige Assembler 'pmovmskb r64, xmm' durch' pmovmskb r32, xmm' ersetzen und einen REX speichern, da sich die 64bit Zielversion identisch verhält. Obwohl der Abschnitt [Operation des Handbuchs] (http://www.felixcloutier.com/x86/PMOVMSKB.html) alle 6 Kombinationen von 32/64-Bit-Ziel- und 64/128/256b-Quellen separat auflistet, ist dies die implizite Null-Erweiterung der r32-Form dupliziert die explizite Zero-Extension der r64-Form. Ich bin gespannt auf die HW-Implementierung ... –

Antwort

55

Ich bin nicht AMD oder für sie sprechen, aber ich hätte es genauso gemacht. Da das Nullsetzen der oberen Hälfte keine Abhängigkeit vom vorherigen Wert erzeugt, müsste die CPU warten. Der Registerumbenennungsmechanismus würde im Wesentlichen besiegt werden, wenn dies nicht so gemacht würde. Auf diese Weise können Sie schnellen 32-Bit-Code im 64-Bit-Modus schreiben, ohne die Abhängigkeiten jederzeit explizit unterbrechen zu müssen. Ohne dieses Verhalten würde jeder einzelne 32-Bit-Befehl im 64-Bit-Modus auf etwas warten müssen, das vorher passiert ist, obwohl dieser hohe Teil fast nie verwendet würde.

Das Verhalten für 16-Bit-Anweisungen ist das seltsame. Der Abhängigkeitswahnsinn ist einer der Gründe, warum 16-Bit-Befehle jetzt vermieden werden.

+7

Ich denke nicht, dass es merkwürdig ist, ich denke, dass sie nicht zu viel brechen wollten und das alte Verhalten dort hielten. –

+3

@Alex, als sie den 32bit-Modus einführten, gab es kein altes Verhalten für den hohen Teil. Vorher gab es keinen hohen Teil. Danach konnte es natürlich nicht mehr verändert werden. – harold

+1

Ich sprach über 16-Bit-Operanden, warum die oberen Bits in diesem Fall nicht auf Null gesetzt werden. Sie tun dies nicht in Nicht-64-Bit-Modi. Und das wird auch im 64-Bit-Modus beibehalten. –

6

Es spart einfach Platz in den Anweisungen und den Anweisungen. Sie können kleine Sofortwerte in ein 64-Bit-Register verschieben, indem Sie vorhandene (32-Bit-) Anweisungen verwenden.

Es erspart Ihnen auch, 8-Byte-Werte für MOV RAX, 42 zu codieren, wenn MOV EAX, 42 wiederverwendet werden kann.

Diese Optimierung ist nicht so wichtig für 8- und 16-Bit-Ops (weil sie kleiner sind) und das Ändern der Regeln würde auch alten Code brechen.

+4

Wenn das stimmt, wäre es nicht sinnvoller gewesen, es zu signieren-erweitern statt 0 zu verlängern? –

+0

@Damien_The_Unbeliever Möglicherweise. Aber Zero-Extension ist extrem günstig. –

+2

@Alex: Und Zeichen-Erweiterung ist nicht? Beides kann sehr kostengünstig in Hardware erfolgen. – jalf