【问题标题】:MIPS' stack causes my brain to overflowMIPS 的堆栈导致我的大脑溢出
【发布时间】: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


【解决方案1】:

以这种方式传递参数只是一个约定。如果您编写一个程序并且您的一个函数正在调用另一个由您编写的函数,您可能还决定传递堆栈上的所有参数(而不是 $a0-$a3)或做任何不同的事情......

但是,当您调用不是由您编写的函数(例如由 C 编译器生成的函数)或您的函数被此类函数调用时,您必须假设不是您编写的函数的行为与此处描述的一样.

当我保存参数时,我必须分配四个空格,对应于前四个参数 ($a0-$a3) 并且永远不要使用它们(如此处所述)。为什么?

早期的 MIPS 处理器是为高端计算机设计的,因此这些约定背后的主要目标是速度而不是可用性。

我只是在想这个“奇怪”的约定:在很多情况下,这个约定会生成尽可能快的代码。所以这就是原因。

我也应该保存“不是额外的”参数吗?

你可以这样做;但是您调用的函数将忽略存储在那里的数据。

在编写自己的编译器时(我已经这样做了),将“非额外参数”存储在堆栈上应该会容易得多 - 所以这可能是这样做的理由。

【讨论】:

    【解决方案2】:

    来自Wikipedia 的 MIPS 调用约定

    32 位 MIPS 最常用的1 调用约定是 O32[2] ABI,它将前四个参数传递给寄存器 $a0-$a3 中的函数;随后的参数在堆栈上传递。堆栈上的空间是为 $a0-$a3 保留的,以防被调用者需要保存其参数,但调用者不会将寄存器存储在那里。返回值存储在寄存器 $v0 中;第二个返回值可以存储在 $v1 中。

    您可以修改$t0,...$t9 寄存器而不将它们保存在堆栈中,但它们可以通过您的代码调用的任何函数进行修改。如果需要使用$s0,...,$s7,则必须将它们保存在堆栈中并在返回前恢复它们。

    【讨论】:

      【解决方案3】:

      以下是关闭线程上热门答案的链接:

      取自:Frame Pointer Explanation

      【讨论】:

        猜你喜欢
        • 2015-05-21
        • 2014-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-02
        • 1970-01-01
        相关资源
        最近更新 更多