x64 アーキテクチャは、x86 の下位互換性のある拡張機能であり、新しい 64 ビット モードと x86 と同じレガシ 32 ビット モードを提供します。 このアーキテクチャでは、x86 の 8 つの汎用レジスタを 64 ビットに拡張し、8 つの新しいレジスタを追加し、最新の 64 ビット プログラミング用の強化された呼び出し規則とアドレス指定モードを導入します。
"x64" という用語には、AMD64 と Intel 64 の両方が含まれます。 命令セットはほぼ同じです。
レジスター
x64 は x86 の 8 つの汎用レジスタを 64 ビットに拡張し、8 つの新しい 64 ビット レジスタを追加します。 64 ビット レジスタには、"r" で始まる名前があります。 たとえば、 eax の 64 ビット拡張は rax と呼ばれます。 新しいレジスタの名前は r8 から r15 です。
各レジスタの下位 32 ビット、16 ビット、および 8 ビットは、オペランドで直接アドレス指定できます。 この直接アドレス指定可能性には、以前はアドレス指定できない下位 8 ビットの esi などのレジスタが含まれます。 次の表では、64 ビット レジスタの下位部分のアセンブリ言語名を指定します。
| 64 ビット レジスタ | 下位 32 ビット | 下位 16 ビット | 下位 8 ビット修正 |
|---|---|---|---|
rax |
eax |
ax |
al |
rbx |
ebx |
bx |
bl |
rcx |
ecx |
cx |
cl |
rdx |
edx |
dx |
dl |
rsi |
esi |
si |
sil |
rdi |
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 |
32 ビット のサブレジスタに出力する操作は、64 ビット レジスタ全体に自動的にゼロ拡張されます。 8 ビットまたは 16 ビットのサブレジスタに出力される操作は、ゼロ拡張されません (この動作は x86 と互換性があります)。
ax、bx、cx、dx の上位 8 ビットは、ah、bh、ch、dh としてアドレス指定できますが、すべての型のオペランドで使用することはできません。
命令ポインター eip と フラグ レジスタは 64 ビット (それぞれ rip と rflags) に拡張されます。
x64 プロセッサには、複数の浮動小数点レジスタも用意されています。
80 ビット x87 レジスタ 8 個。
8 個の 64 ビット MMX レジスタ。 (これらのレジスタは x87 レジスタと重複しています)。
8 個の 128 ビット SSE レジスタの元のセットが 16 に増えました。
呼び出し規則
x86 アーキテクチャとは異なり、C/C++ コンパイラは x64 で 1 つの呼び出し規則のみをサポートします。 この呼び出し規則では、x64 で使用できるレジスタの数が増えました。
最初の 4 つの整数またはポインター パラメーターは、 rcx、 rdx、 r8、 および r9 レジスタで渡されます。
最初の 4 つの浮動小数点パラメーターは、最初の 4 つの SSE レジスタ xmm0-xmm3 で渡されます。
呼び出し元は、レジスタで渡される引数のスタック上の領域を予約します。 呼び出された関数は、この領域を使用してレジスタの内容をスタックにスピルできます。
スタック上の他の引数を渡します。
rax レジスタでは整数またはポインターの戻り値が返され、浮動小数点の戻り値は xmm0 で返されます。
rax、 rcx、 rdx、 r8-r11 は揮発性です。
rbx、 rbp、 rdi、 rsi、 r12-r15 は不揮発性です。
C++ の呼び出し規則も同様です。 このポインターは、暗黙的な最初のパラメーターとして渡されます。 次の 3 つのパラメーターは残りのレジスタで渡され、残りはスタックで渡されます。
アドレス指定モード
64 ビット モードのアドレス指定モードは似ていますが、x86 と同じではありません。
64 ビット レジスタを参照する命令は、64 ビット精度で自動的に実行されます。 たとえば、 mov rax、[rbx] は rbx で始まる 8 バイトを rax に移動 します。
mov 命令の特殊な形式は、64 ビット即時定数または定数アドレスに対して存在します。 他のすべての命令では、即時定数または定数アドレスは引き続き 32 ビットです。
x64 では、新しい rip 相対アドレス指定モードが提供されます。 1 つの定数アドレスを参照する命令は、 rip からのオフセットとしてエンコードされます。 たとえば、 mov rax、[addr] 命令は、 addr + rip から rax に 8 バイトを移動します。
命令ポインターとスタック ポインターを暗黙的に参照する jmp、 呼び出し、 プッシュ、 ポップなどの命令は、それらを x64 の 64 ビット レジスタとして扱います。