命令セット・アセンブリ

ほかの関数を呼ばない関数(葉関数、リーフ関数)では、raをスタックに保存しなくてよい場合が多い。その理由として正しいものはどれか。

  1. A葉関数ではret命令を使わないから
  2. B葉関数の戻り先は、CPUが自動でスタックに積むから
  3. Cほかの関数を呼ばないので、raが上書きされず、戻り先がそのまま残るから
答えと解説を見る

正解:C. ほかの関数を呼ばないので、raが上書きされず、戻り先がそのまま残るから

raは関数を呼ぶjalのたびに上書きされるので、ほかの関数を呼ぶ関数は自分の戻り先を最初にスタックへ保存しなければなりません。葉関数はjalを使わないのでraが壊れず、保存なしでretできます。さらに呼び出し先保存のレジスタも使わなければ、スタックフレームを作る必要すらありません。x86のcall命令は戻り先を必ずスタックに積むので、ここはRISC-Vとの違いです。

  • A. 葉関数もretで戻ります。
  • B. RISC-Vのjalは戻り先をレジスタに入れるだけで、スタックには積みません。
  • C. 正しい。raを書き換えるjalを使わないからです。
この分野を解く 分野ページへ

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

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