【发布时间】:2014-09-06 02:05:46
【问题描述】:
我绝对无法理解 MIPS 的堆栈。堆栈上的空间是通过减去 $sp 寄存器来分配的,堆栈按程序的方向增长,当它增长太多时,它会通过覆盖(或至少尝试)程序而溢出。一旦函数被执行,我必须通过添加我首先减去的相同值来移除堆栈。这对我来说都很好。不过有人告诉我,当我保存参数时,我必须分配四个空格,对应于前四个参数 ($a0-$a3),并且永远不要使用它们(如 here 所述)。为什么?此外,当我构建堆栈时,我必须保存额外的参数。我也应该保存“不是额外”的论点吗? 例如这个C程序的汇编:
void f (int x, int y, int z) {
int array[5], a, b;
if (x >= y && x != z)
g(x+1, y+2, z+3, 4, 5);
else
h(x-1, y-2, z-3, 4, 5, 6, 7);
while (z != 0)
x++
}
我应该将 $a0-$a3 保存在它们各自的堆栈位置吗?我应该将它们保存在 $s0-$s3 中吗?如果我没有 while 部分,我应该不保存它们吗?
【问题讨论】:
-
您链接的页面描述了 Microsoft 特定的调用约定。这不是在 MIPS CPU 上使用堆栈的唯一方式。
-
呃,你不需要在 C 中分配任何堆栈空间。事实上,C 不需要堆栈。您声明具有自动存储持续时间的变量,编译器完成其余的工作。此外,为脑残的 Microsoft 调用约定 +1。
-
@EOF 对不起,我的意思是那个 C 程序的汇编方式。
-
在编写汇编代码时要注意自己访问堆栈。否则,不要打扰,让编译器来处理它。
-
你看过System V ABI for MIPS吗?我不知道它是否与您正在查看的 Microsoft 规范完全匹配,但它相当详细。至于“为什么”,答案最终归结为“因为这就是允许调试器等自动化工具从数据转储中重建堆栈帧的原因”。如果您不想,没有人会强迫您使用任何特定的 ABI。
标签: c assembly stack mips callstack