命令セット・アセンブリ
C言語の関数ポインタを使った呼び出し「(*fp)(x)」は、RISC-Vでは一般にどの命令で行われるか。
- A関数の番地をレジスタに入れて、jalrでそのレジスタの番地へ飛ぶ
- Bjalに関数の番地を即値で書いて飛ぶ
- Cbeqで関数の番地と比べて、等しければ飛ぶ
答えと解説を見る
正解:A. 関数の番地をレジスタに入れて、jalrでそのレジスタの番地へ飛ぶ
関数ポインタの指す先は実行時まで分からないので、命令の中に行き先を書くjalは使えません。そこで、ポインタの値をレジスタに読み込み、「jalr ra, 0(t0)」のようにレジスタの番地へ飛び、戻り先はraに残します。C++の仮想関数や共有ライブラリの関数の呼び出しも、同じような間接呼び出しです。行き先が変わるので、CPUは間接分岐の予測器で行き先を予想します。
- A. 正しい。行き先が実行時に決まる間接呼び出しです。
- B. jalの行き先は命令の中に固定され、実行時に変えられません。
- C. beqは条件分岐で、関数の呼び出しには使いません。