jal
lyszt.netはjalおよびその他のRISC-V命令をより詳しく扱っています。
エンコーディング形式
説明
jal は関数を呼び出します。関数とは、複数の場所から実行でき、その後戻ってくることのできる、名前の付いた命令のまとまりであり、ロジックを一度書けばどこでも使えるようにするものです。関数を呼び出すには二つのことが必要です。プログラムは関数のある場所へジャンプし、その後戻ってこられるように、どこから来たのかを覚えておきます。jal はその両方を行い、その名前は jump and link を意味します。
ジャンプは関数を示すラベルへ向かいます。リンクの部分はジャンプの前に起こります。jal は次の命令、つまり呼び出しのすぐ後の命令のアドレスをレジスタに保存します。関数はその保存されたアドレスを使って戻ります。
慣例により、保存されたアドレスは戻りアドレスを意味する ra という名前のレジスタに入ります。以下の行は square 関数へジャンプし、戻るべきアドレスを ra に残します。
jal ra, square
関数が終了すると、ra にあるアドレスへジャンプすることで戻ります。これは ret 命令が行うことです。同じ呼び出しの通常の省略記法を以下に示します。
call square
RISC-V のマニュアルによれば、ジャンプオフセットは 2 バイトの倍数で数えられ、符号拡張されてジャンプ命令のアドレスに加算されます。これにより、プラスマイナス 1 MiB の範囲が得られます。ここで 1 MiB は 1,048,576 バイトです。jal は次の命令のアドレス、つまり pc プラス 4 を rd に保存します。標準的なソフトウェア呼び出し規約では、x1 を戻りアドレスレジスタとして、x5 を代替リンクレジスタとして使用します。無条件ジャンプ命令は pc 相対アドレス指定を使用し、これは位置独立コード、つまりメモリのどこにロードされても動作するコードをサポートします。
jal は ra を新しい戻りアドレスで上書きします。ある関数が別の関数を呼び出す場合、内側の呼び出しは外側の呼び出しの保存されたアドレスを置き換えます。自身で呼び出しを行う関数は、まず ra を保存し、戻る前にそれを復元しなければなりません。この例は square を呼び出し、戻りアドレスを ra に残します。
例
jal ra, square # call square; ra holds the return address
