x64 アーキテクチャ
x64 アーキテクチャは、x86 の下位互換性のある拡張機能です。 新しい 64 ビット モードと、x86 と同じレガシ 32 ビット モードが提供されています。
"x64" という用語には、AMD 64 と Intel64 の両方が含まれます。 命令セットは、ほぼ同じです。
レジスター
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 と flag レジスタは、それぞれ 64 ビット (rip と rflags) に拡張されています。
x64 プロセッサには、複数の浮動小数点レジスタも用意されています。
8 個の 80 ビット x87 レジスタ。
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++ の呼び出し規則も同様です。 this ポインターは、暗黙的な最初のパラメーターとして渡されます。 次の 3 つのパラメーターは残りのレジスタで渡され、残りはスタックで渡されます。
アドレス指定モード
64 ビット モードのアドレス指定モードは似ていますが、x86 と同じではありません。
64 ビット レジスタを参照する命令は、64 ビット精度で自動的に実行されます。 たとえば、mov rax、[rbx] は rbx で 始まる 8 バイトを rax に移動します。
64 ビット即時定数または定数アドレスに対して、mov 命令の特殊な形式が追加されました。 他のすべての命令では、即時定数または定数アドレスは引き続き 32 ビットになります。
x64 では、新しい rip 相対アドレス指定モードが提供されます。 1 つの定数アドレスを参照する命令は、rip からのオフセットとしてエンコードされます。 たとえば、mov rax, [addr] 命令は、addr + rip から rax に 8 バイト移動します。
命令ポインターとスタック ポインターを暗黙的に参照する jmp、call、push、pop などの命令は、それらを x64 の 64 ビット レジスタとして扱います。