MIPS:为什么我们需要堆栈?
MIPS:为什么我们需要堆栈?
这个问题已经有答案了: 什么是微处理器中堆栈的作用
MIPS中栈的目的是什么,为什么我们需要它?可以给出一个相关的示例代码吗?
考虑下面递归定义的 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
)。