jalr

jalr

RISC-V アセンブリ 参考

lyszt.netはjalrおよびその他のRISC-V命令をより詳しく扱っています。

エンコーディング形式

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

説明

jalrはjalと同じファミリーに属し、rはレジスタを意味します。どちらの命令もジャンプしてリターンアドレスを格納します。これはjalのページで説明されています。違いはジャンプ先です。jalはプログラムを書くときに固定されたラベルへジャンプしますが、jalrはレジスタに保持されたアドレスへジャンプするため、ジャンプ先を実行時に計算できます。

これが関数のリターンを可能にします。呼び出し側はリターンアドレスをraレジスタに入れ、関数はjalrを使ってraのアドレスへ戻ります。ret命令はraへのjalrです。

同じ能力は、ジャンプ先が事前に不明な場合にも当てはまります。アドレスが引数として渡された関数への呼び出しや、アドレステーブルに並んだルーチンの選択、つまり大きなswitch文やインタプリタのディスパッチがこれに該当します。

RISC-Vマニュアルによると、jalrは符号拡張された12ビットの即値をレジスタrs1に加算し、その結果の最下位ビットをクリアします。次の命令のアドレス、pc+4をrdに格納し、リターンアドレスが不要な場合はx0を宛先にできます。luiに続くjalrは任意の32ビット絶対アドレスに到達し、auipcに続くjalrは任意の32ビットpc相対アドレスに到達します。どちらのジャンプ命令も、ターゲットアドレスが4バイト境界に整列していない場合は例外を発生させます。

jalrのフォーマットは以下に示します。レジスタrsのアドレスにオプションの小さなオフセットを加えた先へジャンプし、リターンアドレスをrdに格納します。

jalr rd, rs, offset

jalと同様に、書き込むレジスタは上書きされるため、raを保存する際には同じ注意が必要です。

例

la t0, target
jalr ra, t0, 0   # jump to target; ra holds the return address