MIPS:为什么我们需要堆栈?

28 浏览
0 Comments

MIPS:为什么我们需要堆栈?

这个问题已经有答案了: 什么是微处理器中堆栈的作用

MIPS中栈的目的是什么,为什么我们需要它?可以给出一个相关的示例代码吗?

admin 更改状态以发布 2023年5月21日
0
0 Comments

考虑下面递归定义的 C 函数:\n\n

int f(int n)
{
    if(n<3)
    {
        return n+4;
    }
    else
    {
        return f(n-1)+f(n-2);
    }
}

\n\n你正在调用 f(20)。\n\n以下会发生:\n\n最初,返回地址位于寄存器 $ ra 中。\n\n该函数使用函数参数 f(19) 调用自己,f(19) 返回。到目前为止还不错。现在某个寄存器将包含由 f(19) 返回的值。\n\n现在,该函数使用参数 f(18) 调用自己。\n\nf(19) 返回的值已存储在某个寄存器中。无论如何将覆盖该寄存器。如果 f(19) 在那里写入该值,则在此情况下,f(18) 会覆盖此寄存器,因为 f(19)f(18) 是相同的函数。或者 f(20) 在那里写入该值 ... 好吧,f(20)f(18) 是相同的函数。\n\n在任何情况下,该寄存器都将被覆盖。\n\n因此,在寄存器中存储返回值将不起作用。将值存储在全局变量中如何?\n\n

int intermediate;
int f(int n)
{
    ...
    intermediate = f(n-1);
    return f(n-2) + intermediate;
}

\n\n我们将遇到相同的问题:调用f(18)将覆盖变量intermediate,因此我们无法再执行加法运算...\n\n而当我们从函数返回时,我们遇到了下一个问题:通过调用f(19),我们已经覆盖了$ra...\n\n使用本地变量仅会移动问题:\n\n

int f(int n)
{
    int local;
    ...
}

\n\n=> 我们应在什么位置存储变量local? 在固定的存储器地址(= 全局变量)还是在寄存器中? 在两种情况下,我们都会遇到上述相同的问题。\n\n现在,我们可以考虑以下解决方案:\n\n

int intermediate[100];
int f(int n, int level)
{
    ...
    intermediate[level] = f(n-1, level+1);
    intermediate[level] += f(n-2, level+1);
    ...
}

\n\n因此,f(20) 将使用 intermediate[0],从 f(20) 调用的函数将使用 intermediate[1],从该函数中调用的函数将使用 intermediate[2],依此类推...\n\n这正是 \"stack\" 的概念!\n\n然而,您不必自行实现此方法,而是已经预定义了寄存器 $sp 指向可用的内存(如示例中的 level)。

0