(a) f 的函数 prologue 和 epilogue 对寄存器 $sp、$ra 和 $fp 做了什么,假设 $ra 和 $fp 是函数修改的唯一被调用者保存的寄存器。强>
($fp 是“帧指针”,也称为“基指针”,$sp 是“堆栈指针”,$ra 是“退货地址”)
要解释如何访问“int x”,了解它的存储方式和存储位置很重要。由于 'int x' 是一个局部变量,MIPS 将通过减去字节数( 4) 用于堆栈指针的 32 位整数。调用者的返回地址也被保存(另外 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'('加载单词')。
另外,我知道 MIPS 可能会很痛苦,而 reference sheet 确实帮助了我。