我一直在阅读使用静态(aka访问)链接来实现嵌套过程。除了如何确定到达包含我们想要访问的本地的函数的堆栈帧需要多少“跳”之外,我没有理解这个概念。
许多来源 - 其中,this PDF handout(第4页) - 列出两种情况:
假设f调用g。设nf = f的嵌套级别,ng = g的嵌套级别。我们现在有两种情况:
1)nf< ng ---被调用者的嵌套比调用者更深。因此g在f内部声明,因此静态链接应该指向调用者的堆栈帧。
2)nf> = ng ---嵌套级别相等,或嵌套函数调用包含函数。在这种情况下,请按照
nf - ng + 1
静态链接确定要推送的堆栈帧。
虽然我对案例1没问题,但我真的不明白第二种情况如何起作用。考虑以下伪代码:
procedure A()
{
local u;
procedure B()
{
u = 0;
}
procedure C()
{
B();
}
C();
}
当我们调用A时,会为它创建一个堆栈帧。 A然后调用C,进入调用B.B必须解析对非局部变量u
的引用;根据上面列出的步骤,它应该遍历堆栈上的1 - 1 + 1
静态链接以获得适当的堆栈帧;但是,这样做,它最终会在C的堆栈框架中结束。当考虑递归时,问题变得更加复杂 - 静态嵌套级别不会改变,但是在递归函数的堆栈上将有多个堆栈帧/激活记录。
我认为我的问题来自于以这种或那种方式误解这个概念;如果有人在我的推理中指出了这些缺陷,我将不胜感激。