ImageVerifierCode 换一换
格式:PPT , 页数:29 ,大小:1.08MB ,
资源ID:969853      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.docduoduo.com/d-969853.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(编译原理第九章.ppt)为本站会员(无敌)主动上传,道客多多仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知道客多多(发送邮件至docduoduo@163.com或直接QQ联系客服),我们立即给予删除!

编译原理第九章.ppt

1、编 译 原 理 (第二版),郑 洪 编著,第9章 运行时存储空间管理,9.1 程序运行时的存储环境,一个可执行程序所使用的存储空间被分为两个区间,一是代码区,存放程序的操作指令;二是数据区,存放程序所使用或产生的数据。动态分配数据区的方法有很多种,最典型的情况是将数据区以栈的形式管理。存放动态数据的另一种数据结构被称为堆(heep)。,代码存储区示意,在翻译函数调用语句时有一条语义规则就是创建活动记录,一个活动记录的结构如图。局部数据区里存放着函数定义的局部变量、计算数组单元地址的内情向量、编译过程产生的临时变量等。形式参数单元用以存放函数调用时实际参数的信息。在活动记录的连接数据区中有一个称

2、为“动态链”的信息,动态链就是将所有活动记录的首地址链接成链。当前函数可以顺着活动链找到任何一个其他运行函数的活动记录,并与之交换信息。指针SP是当前运行函数活动记录在栈数据区里的起始位置。,9.2 静态存储分配,静态存储分配是指在编译阶段就能计算出一个程序在运行时所需的全部存储空间的大小,并能够安排好目标程序运行时的全部数据空间,最终为每个数据的存储单元确定地址。在完全静态存储分配的环境下,不仅全局变量,所有的变量都是静态分配存储地址。,【例9.1】下面的程序是一个FORTRAN77程序,由主过程P和一个附加过程Q组成。PROGRAM PCOMMON MAXSINTEGER MAXSREAL

3、 T(10),XX=1.0MAXS=10READ*,T(1),T(2),T(3)CALL Q(T,3,X)SUBROUTINE Q(A,S,Y)COMMON MAXSINTEGER MAXS,SREAL A(S),Y,XINTEGER KX=0.0DO 10 K=1,SIZEX=X+A(K)*A(K)CONTINUEY=SQRT(X/S)RETURNEND,9.3 基于栈的运行时存储器管理,9.3.1 简单的栈式存储管理所有的函数之间只存在调用关系,不存在定义关系。研究一个程序在运行时函数的调用顺序有一个工具,称为“活动树”,每个活动记录或调用都成为该树的一个结点,每个结点的子结点又表示一次调

4、用。【例9.2】利用Euclid算法的简单递归实现计算两个非负整数的最大公约数,C代码如下:#includestdio.hint x,y;int gcd(int u,int v) if(v=0) return u; else return gcd(v,u%v); main() scanf(%d, ,运行时的活动树,调用函数时,构造活动记录的步骤大致如下: 建立控制链,将SP的内容复制到TOP指针所指的单元,这个单元是新活动记录的第一个单元。这里把它作为控制链指针单元。这时新活动记录的控制链指针指向调用函数的活动记录的首地址。 建立新活动记录首地址指针,将TOP的内容复制到SP中,SP指向新活动

5、记录的首地址。 计算实际参数,按活动记录中形式参数区的相对地址存入实际参数,并随时调整TOP指针。 将函数返回地址存放在新活动记录中(主函数不用)。 分配局部数据空间,这里主要是为局部变量准备空间。当这个空间分配完结之后TOP就指向活动记录之外第一个未使用的存储单元,为下一个活动记录做好准备。这时活动记录已构建完毕,程序可以转移到被调用的函数入口。,函数返回时的操作相对简单,大致如下: 将SP的内容复制到TOP,这意味着当前活动记录所占有的空间将重新分配。 将SP指针的内容复制到SP中,因为SP指针的内容是上一个活动记录的首地址,此时当前的活动记录被删除了,消失了。 弹出返回地址。在恢复了原来

6、的活动记录并获得返回地址后,程序就可以转移到调用程序的返回点了。,【例9.3】有一程序如下:int x=2;全局变量void g(int);void f(int n) static int x=1;局部静态变量 g(n); x-;void g(int m) int y=m-1; if(y0) f(y); x-; g(y); main() g(x); return(); ,程序的活动树,g(2)活动记录的运行过程,第2次调用g时的栈数据区的活动记录情况及其对应的活动树,第3次调用g时的栈数据区的活动记录情况及其对应的活动树,9.3.2 过程可局部定义的栈式存储管理如果一个语言允许在过程的内部再定

7、义过程,即程序中并非所有的过程都是全局的。【例9.4】考虑以下PASCAL程序:program Refprocedure p; var n:m integer; procedure q; begin end;(*q*) procedure r(n:integer) begin q; end;(*r*) begin(*p*) n:=1; r(2); end(*p*);begin(*main*) p; end;,显然,在这段程序中,n不是全局的变量,它是在过程p中定义的。它可以被在p中定义的过程q和过程r引用。对于q或r而言,n又不是局部的,因为在q或r里没有n的定义,所以若在q或r里引用n,就称

8、为非局部非全局引用。,由于过程定义是嵌套的,一个过程可以引用包围它的任一外层过程所定义的变量(按标准静态作用域规则)。问题的关键是程序运行如何获得被引用的变量地址。引用时采用“SP偏移量”的寻址方式。1静态链解决这个问题的第一个方法也称“实现静态作用域”,是将一个称为静态链(也称访问链)的额外信息添加到每个活动记录中。静态链的指针指向离本活动记录最近的直接外层过程的记录。,静态链的指针指向离本活动记录最近的直接外层过程的记录,【例9.5】program chain procedure p; var x:integer; procedure q; procedure r; begin x:=2;

9、 ifthen p end(*r*) begin r; end(*q*) begin q; end(*p*) begin(*main*) p;,程序第一次对r调用后的栈数据区 用静态链表示的嵌套层关系,2嵌套层次显示表这与符号表中的Display很相像。每当程序进入一个过程后,在建立活动记录的同时建立Display。如果当前过程的层数为i,则它的Display就有i+1个单元。,在实用的栈式存储管理应用中,往往把Display表插入在活动记录中。例如,可以把它放在“返回地址”单元的上面,并用Display表取代静态链来访问非局部变量。因此上述例子中的栈结构可用图来表示。,9.4 参数传递机制,

10、9.4.1 值传递将实际参数作为函数中要使用的数值直接复制到活动记录中的形式参数区。形式参数在函数中等同于变量,引入实际参数如同为变量赋值。【例9.6】下述程序在过程调用时使用值传递。program main(input,output)var a,b:integer; procedure p(x,y,z) begin y:=y+1; z:=z+x; end;p begin a:=2; b:=3; p(a+b,a,a): print a;end,过程p调用初始时数据区的状态过程p调用结束时数据区的状态,9.4.2 地址传递地址传递也称引用传递,是把实际参数单元的地址复制到形式参数单元内。【例9.

11、7】再次使用例9.6的程序,参数传递方法为地址传递。program main(input,output)var a,b:integer;procedure p(x,y,z) begin y:=y+1; z:=z+x; end;p begin a:=2; b:=3; p(a+b,a,a): print a;end,过程p调用初始时数据区的状态过程p调用结束时数据区的状态,9.4.3 值结果传递值结果传递参数机制的结果与地址传递类似,在函数中直接使用实际参数的值参加运算。当函数退出调用时,将形式参数最终被确定的值复制到实际参数的地址。【例9.8】仍考虑例9.6的代码,参数传递方法为地址传递。pro

12、gram main(input,output)var a,b:integer;procedure p(x,y,z) begin y:=y+1; z:=z+x; end;p begin a:=2; b:=3; p(a+b,a,a): print a;end,过程p调用初始时数据区的状态过程p调用结束时数据区的状态,9.4.4 名字传递生成一个处理实际参数的子程序(称参数子程序)。当被调用过程使用到相应的参数时就调用这个子程序。例如在下述C代码中:int i;int a10;void p(int x) +i; +x; main() i=1; a1=1; a2=2; p(ai); return 0;

13、 ,当main()程序调用p(ai )时,i=1。如果采用名字传递机制,p函数执行+i之后,对参数的引用就不是a1,而是a2,所以这段代码执行的结果是将a2设置为3,而不是将a1设置为2。但若采用地址传递机制,则参数x在函数调用时即被存入a1的地址,此后无论改变与否都不会重新计算x的地址。,再考虑前述例子:program main(input,output)var a,b:integer;procedure p(x,y,z) begin y:=y+1; z:=z+x; end;p begin a:=2; b:=3; p(a+b,a,a): print a;end,当程序调用p函数时,p函数变成如下形式:procedure p(a+b,a,a) begin a:=b+1; a:=a+a+b;end;p函数直接把实际参数当作变量操作,其最后结果是a的值为9。,Thank You !,

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报