【编译原理】活动记录

活动与活动记录

概念:

  • 过程的一次执行称为过程的一次活动
  • 把过程的一个活动所需要的信息组成的一块连续的存储单元 ,称为活动记录

理解:

  • 一个活动所需要的信息的每个数据项有相同的生存周期,因此,将它们组成一个活动记录是很自然的
  • 把活动看作位于栈上的方法(不严谨 ),或许更好理解?
  • 源语言不同,活动记录的域不同——活动记录因语言而异,下面的内容你更能体会到这一点(比如过程能否作为参数?)

 
 

运行时的内存分配

内存被划分为:

目标代码(编译后才知道大小)
静态数据(生命周期是整个活动)
(Stack)
(Heap)

内存分配策略:

  1. 静态的:编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间(这样的话,代码就不能有可变数组,也不能出现递归结构——否则编译时算不出需要的空间大小)
  2. 栈式的:动态分配策略的一种。栈的Push和Pop操作完美契合了程序的运行过程(与函数调用简直天作之合 );缺点也有,在运行之前,即编译时,我们就要知道所需空间的大小。
  3. 堆式的:动态分配策略的一种。如果基于堆进行分配,就不用再去考虑空间大小、生命周期了;代价是更慢的速度。

Java中对Stack/Heap的使用就很值得推荐,new出的对象都在中,上存放有指向它们的引用。这就是题外话了,与编译原理无关 >_<

内存分配影响语言特征:

  • 过程能否递归
  • 过程能否访问非局部变量
  • 过程能否作为参数
  • 过程结束后,其对局部变量的影响能否保留

 
 

PL/0的活动记录(模板)

  • 局部变量
  • 参数
  • 参数个数
  • RA—— 返回地址,填“?”
  • DL—— 动态链(访问链)谁调用了我?
  • SL—— 静态链(控制链)直接外层的SP

 
 

PL/0的活动记录(例题)

procedure P;
var a, b;
	procedure Q(b);
	var i;
		procedure R(u, v);
		var c, d;
		begin
			if(u = 1) then R(u + 1, v);
		end;
	begin
		R(1, x);
	end;
	procedure S;
	var i, j;
	begin
		a = 1;
		Q(a);
	end;
begin
	S;
end.

这里有三层过程。划分好层次,再套用模板 ,题目迎刃而解。

在这里插入图片描述

 
 
 
 

 
 
 
 

 
 
 
 

E N D END END

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值