x64-Architektur
Die x64-Architektur ist eine abwärtskompatible Erweiterung von x86. Es bietet einen neuen 64-Bit-Modus und einen Legacy-32-Bit-Modus, der mit x86 identisch ist.
Der Begriff "x64" umfasst sowohl AMD 64 als auch Intel64. Die Befehlssätze sind nahezu identisch.
Register
x64 erweitert die 8 allgemeinen x86-Register auf 64-Bit und fügt 8 neue 64-Bit-Register hinzu. Die 64-Bit-Register haben Namen, die mit "r" beginnen. Die 64-Bit-Erweiterung von eax wird beispielsweise rax genannt. Die neuen Register heißen r8 bis r15.
Die unteren 32 Bits, 16 Bits und 8 Bits jedes Registers können direkt in Operanden adressiert werden. Dies umfasst Register wie esi, deren niedrigere 8 Bits zuvor nicht adressierbar waren. Die folgende Tabelle gibt die Assemblysprachennamen für die unteren Teile von 64-Bit-Registern an.
64-Bit-Registrierung | Untere 32 Bits | Untere 16 Bits | Untere 8 Bits |
---|---|---|---|
Rax | Eax | ax | al |
rbx | Ebx | Bx | bl |
rcx | ecx | Cx | cl |
rdx | Edx | Dx | Dl |
Rsi | Esi | si | sil |
Fei | Edi | di | Dil |
rbp | Ebp | bp | Bpl |
Rsp | Esp | sp | Spl |
r8 | r8d | r8w | r8b |
r9 | r9d | r9w | r9b |
r10 | r10d | r10w | r10b |
r11 | r11d | r11w | r11b |
r12 | r12d | r12w | r12b |
r13 | r13d | r13w | r13b |
r14 | r14d | r14w | r14b |
r15 | r15d | r15w | r15b |
Vorgänge, die in ein 32-Bit-Unterregister ausgegeben werden, werden automatisch auf das gesamte 64-Bit-Register erweitert. Vorgänge, die in 8-Bit- oder 16-Bit-Unterregister ausgegeben werden, sind nicht mit Null erweitert (dies ist ein kompatibles x86-Verhalten).
Die hohen 8 Bits von ax, bx, cx und dx sind weiterhin als ah, bh, ch, dh adressierbar, können aber nicht mit allen Arten von Operanden verwendet werden.
Das EIP - und flags-Register der Anweisungszeiger wurde auf 64 Bit (rip und rflags) erweitert.
Der x64-Prozessor stellt auch mehrere Gleitkommaregister bereit:
Acht 80-Bit-x87-Register.
Acht 64-Bit-MMX-Register. (Diese Register überschneiden sich mit den x87-Registern.)
Der ursprüngliche Satz von acht 128-Bit-SSE-Registern wird auf sechzehn erhöht.
Aufrufkonventionen
Im Gegensatz zum x86 unterstützt der C/C++-Compiler nur eine Aufrufkonvention für x64. Diese Aufrufkonvention nutzt die erhöhte Anzahl von Registern, die auf x64 verfügbar sind:
Die ersten vier Ganzzahl- oder Zeigerparameter werden in den Registern rcx, rdx, r8 und r9 übergeben.
Die ersten vier Gleitkommaparameter werden in den ersten vier SSE-Registern xmm0-xmm3 übergeben.
Der Aufrufer reserviert Platz im Stapel für Argumente, die in Registern übergeben werden. Die aufgerufene Funktion kann diesen Bereich verwenden, um den Inhalt von Registern auf den Stapel zu übergeben.
Alle zusätzlichen Argumente werden an den Stapel übergeben.
Ein Ganzzahl- oder Zeigerrückgabewert wird im rax-Register zurückgegeben, während ein Gleitkommarückgabewert in xmm0 zurückgegeben wird.
rax, rcx, rdx, r8-r11 sind flüchtig.
rbx, rbp, rdi, rsi, r12-r15 sind nicht volatile.
Die Aufrufkonvention für C++ ist ähnlich. Dieser Zeiger wird als impliziter erster Parameter übergeben. Die nächsten drei Parameter werden in den verbleibenden Registern übergeben, während der Rest im Stapel übergeben wird.
Adressierungsmodi
Die Adressierungsmodi im 64-Bit-Modus sind ähnlich, aber nicht identisch mit x86.
Anweisungen, die auf 64-Bit-Register verweisen, werden automatisch mit einer Genauigkeit von 64 Bit ausgeführt. Beispielsweise verschiebt mov rax, [rbx] 8 Bytes beginnend bei rbx in rax.
Eine spezielle Form der mov-Anweisung wurde für 64-Bit-Sofortkonstanten oder Konstantenadressen hinzugefügt. Für alle anderen Anweisungen sind sofort Konstanten oder Konstantenadressen immer noch 32 Bits.
x64 bietet einen neuen Rip-Relative-Adressierungsmodus. Anweisungen, die auf eine einzelne konstante Adresse verweisen, werden als Offsets von rip codiert. Beispielsweise verschiebt die Anweisung mov rax, [addr] 8 Bytes ab addr + rip nach rax.
Anweisungen wie jmp, call, push und pop, die implizit auf den Anweisungszeiger und den Stapelzeiger verweisen, behandeln sie als 64-Bit-Register auf x64.