レジスタ

x86-64 には64ビットの汎用レジスタが16本あります。それぞれ64ビット(8バイト)、32ビット(4バイト)、16ビット(2バイト)、8ビット(1バイト)のレジスタとして使用することができます。RAX、RBX、RCX、RDXの4本は8ビットのレジスタ2つとして独立にアクセスできます。32ビットレジスタとして書き込まれた場合に上位32ビットは0が書き込まれることに注意してください。16ビット、8ビットレジスタとして書き込まれた場合は上位のビットは変化しません。

汎用レジスタには整数またはメモリアドレスを格納することができます。

RAX、RBX、RCX、RDX、RSI、RDI、RBP、RSP は16bit CPUである 8086の時代(1978年?)から存在するレジスタの64bit拡張版です。したがって汎用レジスタといっても昔の役割が少し残っていて、一部の命令で特殊な役割があります。特にRSPはスタックポインタとして重要な役割があります。

RAX

アキュムレータの「A」です。歴史的に演算専用のレジスタ(アキュムレータ)として始まりましたが、現在では他の汎用レジスタでも演算ができるため大きな違いはありません。他のレジスタを使う場合に比べて定数(即値)を使う演算命令では、命令長が1バイトとなって短い場合があります。64bit x 64bit の乗算の結果(積)の下位64ビットが格納されます。128bit / 64bit の整数除算の場合に被除数の下位64ビットを格納します。除算の結果(商)が格納されます。

Linuxのシステムコールの呼び出しで、システムコール番号の指定に使用し、システムコールの結果が返ります。

7654 3210
RAX
EAX
AX
AH AL

RBX

ベースレジスタの「B」です。16ビットモード(リアルモード)ではメモリアドレスの計算に使用するレジスタでしたが、64ビットモードでは他のレジスタも同じ機能を持つようになったため、単なる汎用レジスタです。

7654 3210
RBX
EBX
BX
BH BL

RCX

カウンタレジスタの「C」です。繰り返し回数を指定するような命令(シフト、ループ、REPプレフィックス付のストリング型命令)で繰り返し回数の設定に使います。その他は汎用レジスタとして使用できます。

Linuxのシステムコールの呼び出しでRCXの内容は保存されません(破壊されます)。

7654 3210
RCX
ECX
CX
CH CL

RDX

データレジスタの「D」です。64bit x 64bit の乗算の結果の上位64ビットが格納されます。128bit / 64bit の整数除算の場合の非除数の上位64ビットを格納します。除算の結果の余り(剰余)が格納されます。その他は汎用レジスタとして使用できます。

Linuxのシステムコールの呼び出しの第 3 引数 の設定に使用します。

7654 3210
RDX
EDX
DX
DH DL

RSI

ソースインデックスレジスタです。インデックスレジスタは元々メモリ位置を示すためのレジスタだったため、今でもインデックスレジスタと呼ばれています。ストリング型の命令でコピー元(ソース)を示す場合に専用に使われます。その他は汎用レジスタとして使用できます。

Linuxのシステムコールの呼び出しの第 2 引数 の設定に使用します。

7654 3210
RSI
ESI
SI
SIL

RDI

デスティネーションインデックスレジスタです。インデックスレジスタは元々メモリ位置を示すためのレジスタだったため、今でもインデックスレジスタと呼ばれています。ストリング型の命令でコピー先(デスティネーション)を示す場合に専用に使われます。その他は汎用レジスタとして使用できます。

Linuxのシステムコールの呼び出しの第 1 引数 の設定に使用します。

7654 3210
RDI
EDI
DI
DIL

RBP ベースポインタ

ベースポインタはENTER命令やLEAVE命令でスタックフレームを作成する場合に使われますが、ENTER命令やLEAVE命令はほとんど使われることはありません。歴史的な理由でスタック内のアクセスに使われることが多いですが、普通のレジスタとして使えます。

7654 3210
RBP
EBP
BP
BPL

RSP スタックポインタ

スタックポインタはサブルーチンコールの戻りアドレスをメモリに自動的に格納したり、PUSH、POP命令でレジスタを一時的に退避、復帰する場合に使われます。直接読み書きすることは余りありません。64ビットモードではESP、SP、SPLのように部分的にアクセスすることはないでしょう。

7654 3210
RSP
ESP
SP
SPL

拡張汎用レジスタ R8 - R15

64ビットモードで追加された汎用レジスタが8本(R8、R9、R10、R11、R12、R13、R14、R15)あります。RAXなどの汎用レジスタと同じ用に使用できますが、REXプレフィックスが必要なため、使う場合には命令長が1バイト多くなります。

Linuxのシステムコールの呼び出しでは、第 4 引数 を R10、第 5 引数 を R8、第 6 引数 を R9 に設定します。Linuxのシステムコールの呼び出しでR11の内容は保存されません。

7654 3210
R8
R8D
R8W
R8B

フラグレジスタ RFLAGS

演算や比較の結果が正負、同じか否かなどで変化するビットが集まっています。上位の42ビットは使用しません(予約領域)。条件分岐(Jcc)、条件転送(CMOVcc)で使います。

byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 0
upper 32bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
reserved (0) reserved (0) I
D
V
I
P
V
I
F
A
C
V
M
R
F
0 N
T
I
O
P
L
O
F
D
F
I
F
T
F
S
F
Z
F
0 A
F
0 P
F
1 C
F

フラグレジスタの各ビットの働きを示します。算術ステータスフラグ(CF,PF,AF,ZF,SF,OF)以外の詳細は省略します。

ID :
Identification フラグ
VIP :
バーチャル割り込み保留
VIF :
バーチャル割り込み
AC :
アラインメントチェック
VM :
仮想86モード
RF :
Resume フラグ
NT :
Nested Task
IOPL :
I/O 特権レベルフィールド
OF :
オーバーフローフラグ。 算術演算の結果が2の補数で表せない大きさの場合にセットされます。
DF
方向フラグ。ストリング命令 (MOVS, CMPS, SCAS, LODS, STOS)の自動インクリメント(set)とデクリメント(clear)を指定して文字列操作の方向を決めます。
IF :
割り込み許可フラグ
TF :
トラップフラグ。デバッグ用のシングルステップモードに移行する。
SF :
符号フラグ。演算結果の最上位ビットと同じにセットされます。2の補数の正負を表します。
ZF :
ゼロフラグ。演算結果がゼロのときにセットされます。
AF :
ビット3からのキャリーやボローが発生した場合にセットされます。
PF :
パリティフラグ。演算結果の下位8ビットのパリティを示します。下位8ビットの1の数が偶数なら1、奇数なら0になります。
CF :
キャリーフラグ。このビットは算術演算、シフト、ローテイト命令で最上位ビットまたは最下位ビットから桁あふれが発生した場合にセットされます。

続く...