编译原理活动记录(虎书)

在很多语言中,当函数返回时,局部与该函数的变量便都会消失。因为一个函数只有在它调用的所有函数都返回以后,它才能返回。所以我们说函数调用是按后进先出的方式进行的。如果在函数的入口处创建局部变量,在函数的出口处删除它们,则可以使用一种LIFO的数据结构(即栈)来存放他们。

栈帧,与通常的栈概念不同,局部变量是(在函数入口处)成批压入,并(在函数出口处)成批弹出。此外,当局部变量在栈中被创建时,它们总是没有立刻初始化。最后,当往栈中压入很多变量之后,还会需要访问压在栈顶之下的较深的变量,所以,这里我们将栈看做是一个大型数组,并带有一个特殊寄存器,即栈指针,它指向栈内的某个存储单元。栈通常只在函数入口处增长,并在函数出口处收缩,它通过增加足以容纳该函数的所有局部变量的一片存储空间来扩大栈。栈中用来存放一个函数的局部变量、参数、返回地址和其他临时变量的这片区域称为该函数的活动记录(activation record)或栈帧(stack frame)。栈在存储器中总是从高地址开始并向低地址方向增长,使得相对于栈指针的偏移总是非负的。

上图为一种栈帧布局,一组有调用着传入的参数(incoming arguments)(技术上,这些传入参数是前一栈帧的一部分,但是它们位于相对帧指针的位移是已知的单元中)。返回地址由CALL指令产生,它告诉当前函数结束时应当将控制返回至何处。有些局部变量分配在栈帧内,另一些局部变量则保存在寄存器中。有时候,存放在寄存器中的局部变量会需要保护到栈帧中,以便为其他用途提供空闲的寄存器;最后,当前函数调用其他函数时,可以用传出参数(outgoing arguments)空间来传递参数。

posted on 2013-04-11 15:38  夜月升  阅读(2368)  评论(0编辑  收藏  举报

导航