【问题标题】:Does sw and lw in MIPS store a value below or above the stack pointer?MIPS 中的 sw 和 lw 是否存储低于或高于堆栈指针的值?
【发布时间】:2026-01-09 16:00:01
【问题描述】:

我的教授给了一个看起来像这样的视频:

在右下角,他在位置 124 写了$ra,而$sp 在位置 128,这意味着第一条 sw $ra, 4($sp) 指令将 $ra 值存储在 4 个字节的位置 less强> 比$sp。但我的书却不一样:

图像暗示 lw 指令将其存储在比$sp 更大、更多正数的位置。那么哪个是对的? lw 和 sw 偏移数字是指高于还是低于$sp 的数字?

【问题讨论】:

    标签: mips computer-science


    【解决方案1】:

    您观察到第一个阶乘存储在堆栈指针上方是正确的,堆栈存储它没有分配,并且必须由调用者分配。

    这有点非标准用法,但在技术上是合法的,因为 MIPS 调用约定要求将任何堆栈帧的顶部 4 个堆栈位置提供给 被调用者。该函数只分配一个 2 字的框架,根据调用约定(允许被调用者使用框架的前 4 个字),它应该至少分配一个 4 字的框架。

    不过,由于阶乘函数除了它自己之外不调用其他函数,这是合法的,并且符合调用约定——从某种意义上说,它的工作是确保一个函数可以调用另一个函数。

    (请注意,在 RISC V(开源 MIPS 后续版本)中,不存在供被调用者使用的 4 字堆栈帧的要求,因此类似的情况在那里不起作用。)


    第二个例子更传统,然而,它也没有分配一个标准大小的框架——一个将前 4 个单词提供给被调用者的框架。尽管如此,它在技术上也不是必需的,并且较少依赖原始调用者(例如main)提供适当的堆栈框架(一个给被调用者的 4 个单词)。


    让我们进一步观察第一个代码示例在堆栈上存储了$ra$a0,这是我们希望保存的寄存器——而后一个示例存储了$s0(我们希望将其保存为这些是专用的非易失性),还有$t0$t1 这似乎是非标准的,因为它们是专用的临时对象。

    【讨论】:

    • 第一个存储在堆栈指针上方 b/c i 它使用 偏移量,并且,它存储 before 调整堆栈指针.因此,被存储的区域是由调用者分配的,而不是被调用者。我直接指的是代码,而不是图表。
    • 是的,很抱歉:上下是主观的,如果我们愿意,我们可以把图表倒过来。它也可以很容易地向左或向右。然而,当我在这种情况下说上面或下面时,我不是用图解的方式说话,而是用数字说话:我认为数字较大的地址是“向上”/较高的,而数字较小的地址是“向下”/较低的,无论图表方向如何.因此,我们(我)说堆栈向下增长,这意味着增加堆栈大小会将堆栈/堆栈指针移向数字较低的地址,无论图表如何。
    • 我认为这是谈论地址的唯一一致方式,“更高”、“上方”和“上方”都意味着数值更大(下方、下方和下方相反)。有些人确实在顶部用数值较高的值绘制图表,以与字面上的较高和数值上的较高相对应;而其他图表的顶部数值较低。在许多情况下,后一种方向更自然,即查看堆栈和/或堆中的结构、对象或数组,我们倾向于“向前”的方向。
    • 两个图的顶部都是高地址,底部是低地址。第一个问题是$sp 移动 两条指令已经完成后,它只显示一条 $sp,因此,最好用旧的 $sp 和一个新的$sp(并且两个具有正偏移量的商店应该相对于旧的$sp进行解释)。第二个图有三个$sp 值,随着时间的推移而不同(a,b,c),这很好,尽管要清楚堆栈的实际内存在它们之间是相同的,只是“顶部”的用法和位置堆栈”不同。
    • 代码序列不同,所以图表应该不同。