Arm64のレジスタ ()

Arm64 は、31 本の 64ビット汎用レジスタスタックポインタ、ゼロレジスタ、プログラムカウンタフラグレジスタ、32本の 浮動小数点(Vector)レジスタ、 浮動小数点演算を制御するFPCR レジスタFPSR レジスタを 持っています。

Arm64 の 64bit モードのレジスタにはシステム関連の多くの特殊なレジスタがありますが、 OS を作る場合以外は必要ないと思われるのでこのシリーズでは省略します。

汎用レジスタ

汎用レジスタとして、64ビットのレジスタを 31 個持っています。レジスタの 名称は x0 から x30 となっています。各々のレジスタはw0 - w30 として 32ビット のレジスタとしても使うことができます。 32番めのレジスタもありますが、 これは命令によって2つの機能うちの1つの機能を持ちます。 1つはゼロレジスタ ( xzr 、wzr )として読み込むと常に 0 となるレジスタ、もうひとつは スタックポインタ (sp) としての機能を指定することになります。 数値のゼロを使う場合は xzr レジスタ、スタックの内容を読み書きする場合は sp と表記します。 xzr と sp の使い道から考えて、同じレジスタ番号を内部で 使用しても矛盾することがないという判断なのでしょう。ウマイこと考えたものです。

以上の文章だけでは大きさの雰囲気が伝わらない気がするので、 表にしてみました。 31個の64ビットレジスタです。

汎用レジスタの31番目の x30 はリンクレジスタと呼ばれ、 分岐命令「bl」の戻りアドレスを保持するレジスタとしても使用します。

byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 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 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 7 6 5 4 3 2 1 0
x0
x1
x2
x3
x4
x5
x6
x7
x8
x9
x10
x11
x12
x13
x14
x15
x16
x17
x18
x19
x20
x21
x22
x23
x24
x25
x26
x27
x28
x29
x30 (link register)

31 個の 64 ビットレジスタは、w0 .. w30 のようにレジスタ名を x ではなく、 w で指定すると32ビットレジスタとして使用できます。 32ビットレジスタとして 読み込んだ場合は、上位32ビットはゼロクリアされます。

byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 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 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 7 6 5 4 3 2 1 0
 w0
 w1
 w2
 w3
 w4
 w5
 w6
 w7
 w8
 w9
 w10
 w11
 w12
 w13
 w14
 w15
 w16
 w17
 w18
 w19
 w20
 w21
 w22
 w23
 w24
 w25
 w26
 w27
 w28
 w29
 w30

スタックポインタ、ゼロレジスタ、プログラムカウンタ

汎用レジスタの他に、スタックトップのアドレスを保持するスタックポインタ、 常にすべてのビットが「0」になっているゼロレジスタ、実行中の命令のメモリ アドレスを保持するプログラムカウンタがあります。 プログラムカウンタは、レジスタの名称(PC)を使って直接読み書きすることはなく、 分岐命令の分岐先やメモリアドレスを指定する場合に、プログラムカウンタからの 相対値として(内部的に) 使うことがあるだけです。

byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 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 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 7 6 5 4 3 2 1 0
xzr
 wzr
sp
 wsp
PC

NZCV レジスタ (フラグレジスタ)

演算命令の結果の状態を保持するフラグは NZCV レジスタに 保持されます。NZCV レジスタは 32 ビットのレジスタです。

byte 3 byte 2 byte 1 byte 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 7 6 5 4 3 2 1 0
N Z C V  
演算結果
ビット フラグ 1 0
31 N 正か 0
30 Z 0 それ以外
29 C キャリー/ボロー発生 桁あふれなし
28 V オーバーフロー オーバーフローなし

条件分岐命令は、このレジスタの各ビットの状態で分岐するか しないかを決定します。フラグの組み合わせは以下のようになります。

cond ニーモニック 意味 フラグ
0000 EQ 等しい Z = 1
0001 NE 等しくない Z = 0
0010 CS or HS キャリーセット C = 1
0011 CC or LO キャリークリア C = 0
0100 MI N = 1
0101 PL ゼロまたは正 N = 0
0110 VS オーバーフロー V = 1
0111 VC オーバーフローなし V = 0
1000 HI > 大きい (符号無し) (C = 1) and (Z = 0)
1001 LS ≦ 小さいか等しい (符号無し) (C = 0) or (Z =1)
1010 GE ≧ 大きいか等しい (符号付) N = V
1011 LT < 小さい (符号付) N <> V
1100 GT > 大きい (符号付) (Z = 0) and (N = V)
1101 LE ≦ 小さいか等しい (符号付) (Z = 1) or (N <> V)
1110 AL Always Any
1111 NV Always Any

NZCV システムレジスタの内容は MRS命令で汎用レジスタにコピーすることができ、 MSR命令で汎用レジスタからNZCV システムレジスタにコピーできます。

    MRS    Xt, NZCV     //  NZCV の Xt への読み出し
    MSR    NZCV, Xt     //  Xt を NZCV に書き込み

浮動小数点(Vector)レジスタ

浮動小数点レジスタは、128ビット全体を使って複数のベクトルの要素を 同時に演算するための Vn レジスタを32本持っています。 ここで n はレジスタの番号で 0 から 31 の値です。

浮動小数点レジスタとメモリ間の読み書きは、汎用レジスタとメモリ間と 同じように簡単に行なえます。 また浮動小数点数の比較結果がそのまま フラグレジスタ(NZCV)に反映されるため、汎用レジスタとおなじ感覚で 扱うことができます。アセンブラでも浮動小数点演算が容易にプログラミング できます

byte 15 byte 14 byte 13 byte 12 byte 11 byte 10 byte 9 byte 8 byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 0
QuadWord
DoubleWord DoubleWord
Word Word Word Word
Halfword Halfword Halfword Halfword Halfword Halfword Halfword Halfword
Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte
v0
v1
v2
v3
v4
v5
v6
v7
v8
v9
v10
v11
v12
v13
v14
v15
v16
v17
v18
v19
v20
v21
v22
v23
v24
v25
v26
v27
v28
v29
v30
v31

ベクトルレジスタとして使う場合は次のようにデータのサイズと数をレジスタ名の 後ろに指定します。

名称サイズとデータ数
Vn.8B 8 bit × 8
Vn.16B 8 bit × 16
Vn.4H 16 bit × 4
Vn.8H 16 bit × 8
Vn.2S 32 bit × 2
Vn.4S 32 bit × 4
Vn.1D 64 bit × 1
Vn.2D 64 bit × 2

また128ビットのVn レジスタ 32本と同じ領域を共有して、 スカラー値(1つの浮動小数点数)を格納するためのレジスタの名称がサイズ毎に 決まっています。小さいサイズのレジスタもそれぞれ 32 本までとなっていて、 1つの128ビットレジスタに小さいサイズのレジスタを詰め込むことはせず、 128ビットのうち下位の領域だけを使います。 128ビットの Qn レジスタ、倍精度浮動小数点数を格納する64ビットの Dn レジスタ、 単精度浮動小数点数を格納する 32 ビットの Sn レジスタ、 半精度浮動小数点数を格納する 16ビットの Hn レジスタ、 バイトデータを格納する Bn レジスタとなります。

byte 15 byte 14 byte 13 byte 12 byte 11 byte 10 byte 9 byte 8 byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 0
QuadWord
DoubleWord DoubleWord
Word Word Word Word
Halfword Halfword Halfword Halfword Halfword Halfword Halfword Halfword
Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte Byte
Qn 128bit
 Dn 64 bit
 Sn 32 bit
 Hn 16 bit
 Bn

ここでも n はレジスタの番号で 0 から 31 の値です。


FPCR レジスタ

FPCR (Floating-point Control Register) レジスタは 32 ビットのレジスタです。整数と浮動小数点間の変換に伴う「丸め」も専用の命令があるため、このレジスタを操作することはないと思います。

byte 3 byte 2 byte 1 byte 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 7 6 5 4 3 2 1 0
  A
H
P
D
N
F
Z
RM
ode
str
ide
  L
e
n
I
D
E
  I
X
E
U
F
E
O
F
E
D
Z
E
I
O
E
 

フラグの意味

フラグbit機能
AHP 26半精度浮動小数点数のフォーマット。0でIEEE 754規格に準拠
DN 25デフォルトのNaNの動作
FZ 24Flush-to-zeroモード。0でIEEE 754規格に準拠
RMode 23:22丸めモード
Stride 21:20AArch64では機能なし
Len 18:16AArch64では機能なし
IDE 15非正規化数入力例外トラップ有効化
IXE 12精度低下例外トラップ有効化
UTE 11アンダーフロー例外トラップ有効化
OFE 10オーバーフロー例外トラップ有効化
DZE 9ゼロ除算例外トラップ有効化
IOE 8Invalid Operation例外トラップ有効化

丸めモード(RMode)

上の表の RMode は演算時の丸め演算を指定するフラグとなっていて、 次のようなモードを持っています。

         3     2     1     0    -1    -2    -3
         +-----+-----+-----+-----+-----+-----+
 RN(00)  |   *->                 <-*         |  四捨五入(最も近い整数)
         +-----+-----+-----+-----+-----+-----+
 RP(01)  |     <---*             <---*       |  値が大きくなる方向
         +-----+-----+-----+-----+-----+-----+
 RM(10)  | *--->                   *--->     |  値が小さくなる方向
         +-----+-----+-----+-----+-----+-----+
 RZ(11)  | *--->                 <---*       |  切り捨て(ゼロに向かって)
         +-----+-----+-----+-----+-----+-----+

FPCR レジスタの内容は MRS命令で汎用レジスタにコピーすることができ、 MSR命令で汎用レジスタから FPCR レジスタにコピーできます。

    MRS    Xt, FPCR     //  FPCR の Xt への読み出し
    MSR    FPCR, Xt     //  Xt を FPCR に書き込み

FPSR レジスタ

FPSR (Floating-point Status Register) レジスタは 32 ビットの レジスタです。 浮動小数点演算関連のシステム情報を保持しています。

FPSR レジスタの内容は MRS命令で汎用レジスタにコピーすることができ、 MSR命令で汎用レジスタから FPSR レジスタにコピーできます。

    MRS    Xt, FPSR     //  FPCR の Xt への読み出し
    MSR    FPSR, Xt     //  Xt を FPCR に書き込み
byte 3 byte 2 byte 1 byte 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 7 6 5 4 3 2 1 0
N ZCVQ
C
  I
D
C
  I
X
C
U
F
C
O
F
C
D
Z
C
I
O
C

FPCR の N、Z、C、V フラグは 64 ビットモードでは使われず、 NZCVレジスタ (フラグレジスタ) を使用します。


次はロード命令