命令セット・アセンブリ

RISC-Vの呼び出し規約で、t0〜t6は「呼び出し元保存(caller-saved)」のレジスタである。ある関数がt0に入れた値を、別の関数を呼んだ後も使いたいとき、正しい対応はどれか。

  1. A何もしなくても、呼ばれた関数がt0を必ず元に戻してくれる
  2. Bt0はほかの関数から書き換えられないので、そのまま使える
  3. C呼ぶ前にt0の値をスタックなどに退避し、呼んだ後に戻す
答えと解説を見る

正解:C. 呼ぶ前にt0の値をスタックなどに退避し、呼んだ後に戻す

t系のレジスタは、呼ばれた関数が保存せずに自由に使ってよいことになっています。そのため、呼んだ後も値が必要なら、呼ぶ側が自分で退避しておく必要があります。保存の責任を、呼ぶ側と呼ばれる側でレジスタごとに分けておくと、多くの関数は保存の手間なく一時用のレジスタを使え、全体の保存と復元の回数を減らせます。

  • A. t系は呼ばれた側が自由に壊してよいレジスタです。
  • B. どの関数もt0を自由に使えます。
  • C. 正しい。または最初から保存されるsレジスタに置きます。
この分野を解く 分野ページへ

命令セット・アセンブリのほかの問題

  1. ほかの関数を呼ばない関数(葉関数、リーフ関数)では、raをスタックに保存しなくてよい場合が多い。その理由として正しいものはどれか。
  2. RISC-Vの関数の先頭で「addi sp, sp, -16」を実行する目的として正しいものはどれか。
  3. RISC-Vの標準の呼び出し規約では、関数に入るときのスタックポインタspを16バイトの倍数にそろえることになっている。その理由として最も適切なものはどれか。
  4. 上のコードは、ある関数の先頭(プロローグ)である。この部分が行っていることとして正しいものはどれか。
  5. 関数の中でフレームポインタ(RISC-Vではs0/fp)を使う利点として正しいものはどれか。