c - 函数调用 mip

标签 c mips

假设我们正在检查只有一个局部变量 x 的函数 f 的 MIPS 汇编代码:

void f(void) {
int x;
...
}

我有两个问题:

  1. 假设 $ra 和 $fp 是唯一被函数修改的被调用者保存的寄存器,f 的函数序言和结尾对寄存器 $sp、$ra 和 $fp 做了什么。

  2. f 的 MIPS 汇编代码如何访问变量 x。

我的尝试: 函数序言将寄存器 $ra 和 $fp 保存到调用堆栈中。函数 epilogue 通过将它们从堆栈中弹出并将控制返回到 $ra 中的地址来恢复这些寄存器。不确定 MIPS 如何访问变量 x,但我知道局部变量也存储在堆栈中。

最佳答案

(a) What does the function prologue and epilogue for f do to the registers $sp, $ra and $fp assuming $ra and $fp are the only callee-saved registers modified by the function.

($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) How does the MIPS assembly code for f accesses the variable x.

要访问“int x”,函数“f”可以将变量加载到临时寄存器中。

lw $t0, 0($sp)  #it can be any temporary register

由于局部变量不会跨函数调用保留,因此可以将它们存储在临时寄存器中。本质上,“push”指令是“sw”(“store word”),“pop”指令是“” lw' ('加载词').

此外,我知道 MIPS 可能会很痛苦,而这 reference sheet真的帮助了我。

关于c - 函数调用 mip,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11038606/

相关文章:

java - 使用高级编程语言的简化 MIPS CPU

c - 共享内存中的指针数组

c++ - OpenMP 和 CPU 亲和性

c - MIPS/C 中的钻石排序

io - MIPS 文件打开

c++ - 使用 vector 引起的段错误

c - 我正在学习 C 编程递归并正在做一项事件,但我陷入困境

代码中的 C 段错误(核心转储)错误

我可以减去或比较受限制的指针吗?

assembly - 负载词和移动词之间的区别?