CPU はメモリに格納されている32ビット (4バイト) の命令をメモリアドレスの 小さい方から大きい方に向かって順に実行する。
この命令の実行順を変更する 命令が分岐命令。 実行中の命令のメモリアドレスはプログラムカウンタ (PC) が保持していますが、分岐命令はプログラムカウンタの値を書き換える命令と 考えられる。
実行するメモリアドレスに無条件にジャンプする 「B」と「BR」、呼び出し元(ジャンプした次の命令)に戻る準備をして分岐する 「BL」と「BLR」、呼び出し元へジャンプして 戻る「RET」、条件フラグの値によって分岐したり、直後の命令を順に実行したりする 条件分岐命令(B.EQ、B.GTなど) がある。
## 無条件分岐命令
### B
分岐命令の B は、プログラムカウンタの値にオフセットを加えたメモリアドレスに 分岐(ジャンプ)。 分岐先の命令に付けたラベルを分岐先として指定しますが、 アセンブラが「B」命令の アドレスとラベルのアドレスから、プログラムカウンタ相対オフセットを計算
B label
### BR
分岐命令の BR は、分岐先のメモリアドレスを汎用レジスタに格納して実行することで 、汎用レジスタが格納しているメモリアドレスへの無条件分岐
BR Xn
### BL
リンク付分岐命令の BL は、プログラムカウンタの値にオフセットを加えた メモリアドレスに分岐(ジャンプ)。 分岐先の命令に付けたラベルを分岐先として指定しますが、 アセンブラが「BL」命令のアドレスとラベルのアドレスから、 プログラムカウンタ相対オフセットを計算
BL label
### BLR
リンク付分岐命令の BLR は、分岐先のメモリアドレスを汎用レジスタに格納して 実行することで、汎用レジスタが格納しているメモリアドレスへの無条件分岐
BLR Xn
### RET
RET (Return) 命令は、指定したレジスタのアドレスに無条件分岐。 レジスタを指定しない場合はリンクレジスタ(X30) を指定したことになる
RET { Xn }
### サブルーチン呼び出し
// 呼び出し元 Main: 略 bl Sub // サブルーチン呼び出し mov x0, xzr // X30に格納される戻り先 略 // サブルーチン Sub: // このラベルにジャンプ stp x0, x30, [sp, #-16]! // リンクレジスタ(X30)の退避 stp x1, x2, [sp, #-16]! // レジスタの PUSH の例 // 何か処理 ldp x1, x2, [sp], #16 // レジスタの POP の例 ldp x0, x30, [sp], #16 // リンクレジスタ(X30)の復帰 ret // 呼び出し元の次の命令に戻る
### 条件分岐命令
EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV
### CBZ
CBZ Wt, label CBZ Xt, label
### CBNZ
汎用レジスタ(Rt)の値が 0 でなければ、ラベルに分岐
CBNZ Wt, label CBNZ Xt, label
### TBZ
TBZ(Test bit and Branch if Zero)命令は汎用レジスタ(Rt)の imm で指定した ビット(0..63) が 0 ならばラベルに分岐
TBZ Wt, #imm, label TBZ Xt, #imm, label
### TBNZ
TBNZ (Test bit and Branch if Nonero) 命令は汎用レジスタ(Rt)の imm で指定した ビット(0..63) が 1 ならばラベルに分岐
TBNZ Wt, #imm, label TBNZ Xt, #imm, label
## 条件実行命令
### CSEL
条件が真ならば Rd に Rn を返します。条件が偽ならば Rd に Rm を返します。 条件はサフィックスで指定します。
CSEL Wd, Wn, Wm, 条件 CSEL Xd, Xn, Xm, 条件
### CSET
条件が真ならば Rd に 1 を返し、偽ならば Rd に 0
CSET Wd, 条件 // CSINC Wd, WZR, WZR, 逆条件 CSET Xd, 条件 // CSINC Xd, XZR, XZR, 逆条件
### CSINC
条件が真ならば Xd に Rn
CSINC Wd, Wn, Wm, 条件 CSINC Xd, Xn, Xm, 条件
### CSINV
条件が真ならば Rd に Rn を返します。 条件が偽ならば Rm のビット毎の反転(1の補数)を Rd に
CSINV Wd, Wn, Wm, 条件 CSINV Xd, Xn, Xm, 条件
### CSNEG
条件が真ならば Rd に Rn を返します。 条件が偽ならば Rm が符号付整数として2の補数(正負反転)を Rd に
CSINV Wd, Wn, Wm, 条件 CSINV Xd, Xn, Xm, 条件
## 条件比較
### CCMP (イミディエート)
指定した条件(サフィックス)が真の場合は、 汎用レジスタと5ビットの符号なし整数 (0..31) を比較した結果で 条件フラグを設定し、指定した条件(サフィックス)が 偽の場合は、4ビットのNZCV定数(0..15)を条件フラグに設定
// NZCV = if cond then CMP(Wn, uimm) else nzcv. CCMP Wn, #imm, #nzcv, cond CCMP Xn, #imm, #nzcv, cond
### CCMP (レジスタ)
指定した条件(サフィックス)が真の場合は、 汎用レジスタ Rn と Rm を比較した結果で条件フラグを設定し、 指定した条件(サフィックス)が偽の場合は、 4ビットのNZCV定数(0..15)を条件フラグに設定
// NZCV = if cond then CMP(Rn,Rm) else uimm4. CCMP Wn, Wm, #nzcv, cond CCMP Xn, Xm, #nzcv, cond
### CCMN (イミディエート)
指定した条件(サフィックス)が真の場合は、 汎用レジスタと、5ビットの符号なし整数 (0..31) に -1 を乗じた数を比較した結果で 条件フラグを設定し、指定した条件(サフィックス)が 偽の場合は、4ビットのNZCV定数(0..15)を条件フラグに設定
// NZCV = if cond then CMP(Xn,-uimm5) else uimm4. CCMN Wn, #imm, #nzcv, cond CCMN Xn, #imm, #nzcv, cond
### CCMN (レジスタ)
指定した条件(サフィックス)が真の場合は、 汎用レジスタ Rn と、Rm に-1を乗じた数を比較した結果で条件フラグを設定し、 指定した条件(サフィックス)が偽の場合は、 4ビットのNZCV定数(0..15)を条件フラグに設定
// NZCV = if cond then CMP(Rn,-Rm) else uimm4. CCMN Wn, Wm, #nzcv, cond CCMN Xn, Xm, #nzcv, cond
### ビット操作
REV, REV16, REV32, RBIT, CLS, CLZ
### ステータスレジスタの操作
MRS, MSR
### システムコール
SVC (Supervisor Call) 命令はシステムコール用の命令
SVC #0
.text .global _start _start: mov x2, #13 // x2 length adr x1, msg // x1 string address mov x0, #1 // x0 stdout mov x8, #64 // sys_write svc #0 mov x0, xzr mov x8, #93 // sys_exit svc #0 msg: .asciz "hello, world\n"