assembly - MIPS:堆栈指针($sp)和堆栈的相关用途

标签 assembly mips

目前我正在为我的计算机组织期中学习,我正在尝试完全理解堆栈指针和堆栈。我知道围绕这个概念的以下事实:

  • 遵循先进后出原则
  • 向堆栈中添加一些东西需要两个步骤:
    addi $sp, $sp, -4
    sw $s0, 0($sp)
    

  • 我认为阻止我完全理解的是,我无法提出一个相关的、不言自明的情况,我需要和/或想要使用堆栈指针跟踪数据。

    有人可以详细说明这个概念并给我一些有用的代码示例吗?

    最佳答案

    堆栈的一个重要用途是嵌套子程序调用。

    每个子程序可能有一组该子程序的局部变量。这些变量可以方便地存储在堆栈帧中的堆栈中。一些调用约定也会在堆栈上传递参数。

    使用子例程还意味着您必须跟踪调用者,即返回地址。
    一些架构为此目的有一个专用堆栈,而其他架构则隐式使用“普通”堆栈。默认情况下,MIPS 仅使用寄存器,但在非叶函数(即调用其他函数的函数)中,返回地址被覆盖。因此,您必须保存原始值,通常在局部变量中的堆栈上。调用约定还可能声明必须在函数调用之间保留一些寄存器值,您可以类似地使用堆栈保存和恢复它们。

    假设你有这个 C 片段:

    extern void foo();
    extern int bar();
    int baz()
    {
        int x = bar();
        foo();
        return x;
    }
    

    MIPS 程序集可能如下所示:

    addiu $sp, $sp, -8  # allocate 2 words on the stack
    sw $ra, 4($sp)      # save $ra in the upper one
    jal bar             # this overwrites $ra
    sw $v0, ($sp)       # save returned value (x)
    jal foo             # this overwrites $ra and possibly $v0
    lw $v0, ($sp)       # reload x so we can return it
    lw $ra, 4($sp)      # reload $ra so we can return to caller
    addiu $sp, $sp, 8   # restore $sp, freeing the allocated space
    jr $ra              # return
    

    关于assembly - MIPS:堆栈指针($sp)和堆栈的相关用途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15100476/

    相关文章:

    assembly - 为什么编译器保留一点堆栈空间而不是整个数组大小?

    c - '[' 标记之前的汇编语言解析错误

    assembly - LC3 LEA 指令和存储的值

    c++ - 核心转储中缺少共享库负载偏移

    assembly MIPS 仅使用 BEQ 评估差异

    assembly - SIMD 按变量旋转

    c - 键盘处理程序导致段错误 (djgpp)

    c - 在管道图中,数据危险的数据转发如何工作

    mips - 查找代码片段的偏移量

    mips - 动态与静态指令数