(a) f の関数プロローグとエピローグは、レジスタ $sp、$ra、および $fp に対して、関数によって変更される唯一の呼び出し先保存レジスタが $ra と $fp であると仮定して、何を行いますか。
( $fpは「ベース ポインター」とも呼ばれる「フレーム ポインター」、$spは「スタック ポインター」、および$raは「リターン アドレス」です)
' int x ' がどのようにアクセスされるかを説明するには、それがどこにどのように格納されているかを知ることが重要です。' int x ' はローカル変数であるため、MIPS は 32 ビット整数のバイト数 (4) を差し引いて、スタック上の整数に適切なスペースを割り当てます (または、スペースがある場合は、markgz が話していたメソッドを使用します)。スタックポインタから。関数が呼び出し元にリンクできるように、呼び出し元の戻りアドレスも保存されます (さらに 4 バイト)。
sub $sp, $sp, 8 #4 bytes for $ra + 4 bytes for 'int x' = 8 bytes allocated
sw $ra, 4($sp) #note the order, $ra is always first
sw [int x], 0($sp)
また
addi $sp, $sp, -8 #an alternate to the code above
sw $ra, 4($sp)
sw [int x], 0($sp)
同様に、関数呼び出しの最後に、関数はスタック上のスペースの割り当てを解除することにより、呼び出し元にレジスタを復元します。
lw [int x], 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
フレーム ポインター ( $fp )の使用経験はあまりありませんが、スタック ポインター ( $sp ) が手順中に値を変更すると、参照ポイントとして使用できなくなるため、( $fp ) はそれは場所です($ spは単なる別のレジスタです)。
(b) f の MIPS アセンブリ コードは変数 x にどのようにアクセスしますか。
' int x ' にアクセスするには、関数 ' f ' で変数を一時レジスタにロードできます。
lw $t0, 0($sp) #it can be any temporary register
ローカル変数は関数呼び出し間で保持されないため、一時レジスタに格納できます。基本的に、' push ' 命令は ' sw ' ('store word') になり、' pop ' 命令は ' lw ' ('load word') になります。
また、MIPS が面倒な場合があることも知っていますが、このリファレンス シートは本当に役に立ちました。