文档介绍:过程活动记录(Activation Record)和栈
过程活动记录(AR):
每当过程/函数被调用时,为其分配的局部空间的一种统一结构。
存放在栈区的一段连续的存储单元中,由目标程序进行管理。
是过程一次活动的一个现场记录。
控制信息
返回地址
返回值
临时变量
形参
局部变量
活动记录
1
可编辑版
栈区的组织
AR链或动态链
程序运行时,每调用一个函数,就要为其分配一段连续空间,用于存放该函数运行时的各种信息(过程活动记录AR),函数运行结束返回时,其活动记录就要释放掉;
在当前AR中保存前一个AR首地址,这样形成了一个链表;
Current AR:当前栈顶的AR;
Current Function:当前AR对应的函数;
AR0
nil
AR1
AR2
2
可编辑版
活动记录的详细结构
活动记录
动态链地址
返回地址
返回值
临时变量
形 参
局部变量
过程层次
空间大小
寄存器状态
变量访问环境
sp
offset
InitOff
3
可编辑版
AR中每一项的详细解释
sp:指向当前AR空间的首地址;(寄存器)
动态链地址:
动态链地址对应的就是当前函数的调用函数的AR首地址;
返回地址:
保存本函数执行结束后应返回的代码地址;
即当前函数调用的下一条代码的地址;
活动记录长度:当前活动记录的空间大小;
过程层次:本函数的层数;
4
可编辑版
AR中每一项的详细解释
寄存器状态:保存在函数调用之前的所有寄存器的值;
返回值:保存函数的返回值;
访问环境:
保存相关信息,方便确定变量的存储地址;
对于C语言来讲,可以不用(因为层数最大为1);
形参变量区:存放参数的值的空间;
局部变量区:存放局部变量的值的空间;
临时变量区:存放临时变量的值的空间;
5
可编辑版
AR的例子
#define n 2
int sum = 0;
int fac(int i)
{ if (i==0) return 1;
if (i<0) return -1;
return (i*fac(i-1));
}
void main ()
{
sum = fac(n);
}
6
可编辑版
活动记录的管理
Who?
目标代码完成AR的管理;
When?
函数调用时: f(e1, …, en)
函数返回时:return
How?
调用时—申请活动记录空间并填写相关内容
返回时----释放活动记录的空间等
7
可编辑版
活动记录的填写
对应实际函数调用
四元式包括
(VALACT, result, offset, size)
(CALL, f, true, t)
需要做的事情
将实参放到对应的形参单元中;
将t(返回值应存放的变量)的地址存放在返回值单元;
把sp的值放到动态链地址单元;
填写层数; (可能不一定需要)
保存返回地址(当前目标代码地址);
保存变量访问环境;(可能不一定需要)
保存AR长度size; (可能不一定需要)
改变sp的值;
转向f 的入口地址;
动态链地址
返回地址
返回值
临时变 量
形 参
局部变 量
过程层次
空间大小
寄存器 状态
变量访问 环境
sp
CurrentAR
8
可编辑版
活动记录的填写
对应形参函数调用
四元式包括
(VALACT, result, offset, size)
(CALL, f, false, t)
需要做的事情
确定f作为形参的(level和offset);
在当前的AR的形参区中可以找到对应的地址, 其中存放的是对应实际函数的(层次,空间大小,入口地址);
根据上述信息, 做实际函数调用的事情;
动态 链地址
返回 地址
返回值
临时变量
形 参
局部变量
过程 层次
空间 大小
寄存 器状态
变量访 问环境
sp
CurrentAR
9
可编辑版
活动记录的释放
对应函数返回
四元式包括
(ENDFUNC, _, _, _)
需要做的事情
恢复寄存器;
改变sp的值,
sp = 动态链地址空间存的值;
转向返回地址对应的代码执行;
……
动态链地址
返回地址
返回值
临时变量
形参
局部变量
过程层次
空间大小
寄存器状态
变量访问环境
sp
PreAR
10
可编辑版