编译原理陈火旺版9章9

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第九章 运行时存储空间组织
概述:编译程序必须分配目标程序运行时的数据空间
9.1目标程序运行时的活动
一. 过程的活动
过程与活动
过程的每一次运行(或执行)被称为一次活动(activation)。
活动是一个动态的概念,除了设计为永不停机的过程(如操作系
统等),或者是因设计错误而出现死循环的过程之外,任何过程 的活动均有有限的生存期(life time)。
存放动态数据(如链表等)
二. 活动记录
为管理过程的活动,用一个活动记录来表示其相应的 所有信息: TOP 其中: 临时单元 1. 临时单元、内情向量、局部变量 内情向量 为局部数据区; 局部变量 2. 形式单元:存放实在参数的地址 形式单元 或值;
3. 静态链:指向直接外层过程的最 新活动记录,用于访问非局部变量;
9.2
存放编译时可确定 运行时存储器的划分 大小的数据对象
一、存储器的划分
程序运行时Leabharlann Baidu须由操作 系统分配一定的存储空间, 编译程序应完成对该存储空 间划分:
过程的活动在编译 时不确定,在运行 时当有新过程被调 用,则将该过程的 相关数据放入栈中, 栈的lifo特性正好对 应过程的嵌套调用
目标代码 静态数据 栈 ↓ ↑ 堆
p262(a)
临时工作单元 临时工作单元 内情向量 内情向量 简单变量 简单变量 display 形式单元 形式单元 参数个数 参数个数 静态链 全局 display 返回地址 返回地址 老 SP( ) 老动态链 SP
0层(主过程)的display仅含一项:0层SP;
1层的display含两项: 0层的display+1层SP; …… i层的display含i+1项:i-1层的display+i层SP; Display表的生成过程: 设过程p1调用p2,则p1与p2的 静态关系如右图所示有(a), (b) 两种情况: (a) p1是p2的外层,由p1的display加 上p2的SP即生成P2的display; (b) p1与p2同层,且有共同的外层, 由p1 display表的前 i 项(p2为i层) 加上p2的SP即生成P2的display。 p1 p2 p2 p1
示例见教案
(a)
(b)
作业 Program ex; a:integer; procedure pp(x:integer); begin x:=5; a:=x+1 end; begin a:=2; pp(a); write(a) end. (1) 写出传值、传地址程序的运行结果 (2) 画出ex调用pp(a)前后的活动记录(含display表)
SP: 总是指向现行过程活动记录的起点,用于局 部数据的访问;
TOP:始终指向已占用的栈顶单元。 一. C 的活动记录 TOP 对任何局 临时工作单元 部变量或形 内情向量 参的引用均 简单变量 可表示为: 相当于动态链 形式单元 X[SP], X表 参数个数 示变量的相 返回地址 对地址。
SP
老 SP
二、嵌套层次显示表(display) 和活动记录 为了提高访问非局部变量的速 度,动态组织一个嵌套层次显示表 (display)放入活动记录中。 display中存有本层及各外层的最新 活动记录首地址。为了快速动态生 成display表,需将调用过程的 display表地址(全局display)作为连 接数据传递,因此,活动记录结构 改为右图所示:
9.4 简单的栈式存储分配
以C语言为例,由于不允许嵌套定义过程,但允许过 程递归调用,因此可采用简单的栈式存储分配。 全局数据说明 例有右边的程序结构: Main( ) 当 Main调用了Q, Q { Main中的数据说明 又调用了R后,其存 Q ;} 储空间分配如下: void R( ) TOP { R中的数据说明 R的活动记录 SP } Q的活动记录 .. void Q( ) Main的活动记录 { Q中的数据说明 全局数据区 R;}
9。5 嵌套过程语言的栈式实现 9.5.1非局部名字的访问实现 一、静态链和活动记录 结构: 临时单元 TOP 内情向量 简单变量 形参单元
形参个数
静态链 返回地址 SP 动态链(老SP)
对于像pascal这样的允许过程嵌套的语言,在活动记录中应有“静态链”, 它指向直接外层过程的最新活动记录,用于访问各外层的变量(非局部变量)。 见P260(图9.17 (b))
:传地址、传值、传名、得结果
例:写出参数传递的结果 Program simple(output); var x:integer; procedure change(y:integer); begin y:=1 end; begin x:=0; change(x); write(x) end. 传值: x=0 传地址: x=1
为讨论方便,将过程、函数均视为过程。 一个过程的活动是指该过程的一次执行。 过程的活动生存期是指从该过程体第一步操作到最 后一步操作之间的操作序。两个过程的活动生存期或 嵌套或不重叠。 一个标识符说明在程序中能起作用的范围称为该说 明的作用域。 ex: Fig 9.1 program
二、参数传递
二. C 的过程调用、过程进入、过程返回 1. 过程调用 如前所述,过程调用的三地址码序列为:
par T1 par T2 … par Tn (i+3)[TOP]:=Ti (传值) 应翻译为: 或 (i+3)[TOP]:=addr (Ti) (传地址)
call p, n
1[TOP]:=SP (老sp) 应翻译为: 3[TOP]:=n (传送参数个数) JSR P (转子 指令)
4. 动态链:指向调用本过程的最新 活动记录的起始地址;
静态链 动态链 返回地址
SP
每个活动记录的大小在编译时可以确定( 除动态数据 ), 因此以SP为变址器可方便的访问各个数据。
三. 存储分配策略
静态存储分配:编译时对所有数据对象分配固定的存 储单元(地址空间),运行时始终不变。 栈式动态存储分配:每个过程建立活动记录,运行时每 当调用一个过程,就将活动记录动态的分配于栈顶,过 程活动结束,则活动记录退出栈顶。 堆式动态存储分配:将存储空间组织成堆结构,以便用 户可以随时申请或释放存储空间。 一个编译系统采取怎样的分配策略,取决于源语言中作 用域及生命期的定义规则。
2. 过程进入
进入过程后,应执行以下指令,为新活动记录赋初值 SP:=TOP+1 1[SP]:=返回地址 TOP:=TOP+L (L为活动记录的单元数) 3. 过程返回 对于以 return(E) 或 end 为结束返回的过程,应执行 以下指令: TOP:=SP-1 以 return(E)返回时,还应将 SP:=0[SP] E的值计算出来并放于临时变 X:=2[TOP] 返址 量T中,传回。 UJ 0[X] 无条件转移
相关文档
最新文档