命令セット・アセンブリ

上のコードは、ある関数の先頭(プロローグ)である。この部分が行っていることとして正しいものはどれか。

addi sp, sp, -16
sw   ra, 12(sp)
sw   s0, 8(sp)
  1. Aスタックに領域を確保し、戻り先(ra)と呼び出し先保存のs0を保存している
  2. B関数の引数ra・s0をスタックから読み込んでいる
  3. C関数から戻るために、スタックを解放している
答えと解説を見る

正解:A. スタックに領域を確保し、戻り先(ra)と呼び出し先保存のs0を保存している

1行目でspを16減らしてスタックフレームを確保し、2行目で戻り先のraを、3行目で呼び出し先保存のs0をフレームに書き込んでいます。この関数はほかの関数を呼ぶのでraを、s0を使うのでその元の値を守る必要があります。関数の最後のエピローグでは「lw s0, 8(sp)」「lw ra, 12(sp)」「addi sp, sp, 16」「ret」と逆の手順で戻します。

  • A. 正しい。終わりの部分(エピローグ)で逆の順に戻します。
  • B. swは書き込み(ストア)で、raもs0も引数ではありません。
  • C. spを減らしているので、確保です。
この分野を解く 分野ページへ

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

  1. 関数の中でフレームポインタ(RISC-Vではs0/fp)を使う利点として正しいものはどれか。
  2. RISC-Vで、自分自身を呼び出す再帰関数を書くときに、raをスタックに保存し忘れるとどうなるか。
  3. リトルエンディアンのRISC-Vで、0x12345678の入ったレジスタを「sw」で番地0x100に書き込んだ。その後「lbu」で番地0x101の1バイトを読むと、値はいくらか。
  4. RISC-Vで4バイトを読むlw命令の番地が4の倍数でない(境界がそろっていない)とき、起こりうることとして正しいものはどれか。
  5. RISC-Vの命令「slli t0, a0, 3」の結果t0は、a0の値の何倍になるか(あふれは考えない)。