编译原理课件chap08(陈火旺).ppt.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《编译原理课件chap08(陈火旺).ppt.ppt》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课件 chap08 陈火旺 ppt
- 资源描述:
-
1、第八章 运行时存储空间组织 8.1 静态存储分配静态存储分配 8.2 简单的栈式存储分配简单的栈式存储分配 8.3 嵌套过程语言的栈式实现嵌套过程语言的栈式实现 8.4 堆式动态存储分配堆式动态存储分配 第八章 运行时存储空间组织第九章 运行时存储空间组织 编译程序在完成词法、语法和语义分析后,在编译程序在完成词法、语法和语义分析后,在生成目标代码之前,需要把程序的静态正文和实现生成目标代码之前,需要把程序的静态正文和实现这个程序的运行时的活动联系起来这个程序的运行时的活动联系起来,弄清楚将来在代弄清楚将来在代码运行时刻,源代码中的各种变量、常量等用户定码运行时刻,源代码中的各种变量、常量等用
2、户定义的量是如何存放的,如何去访问它们。义的量是如何存放的,如何去访问它们。 在程序的执行过程中,程序中数据的存取是通在程序的执行过程中,程序中数据的存取是通过与之对应的存储单元来进行的。在程序语言中,过与之对应的存储单元来进行的。在程序语言中,程序使用的存储单元都是由标识符来表示的。它们程序使用的存储单元都是由标识符来表示的。它们对应的内存地址都是由编译程序在编译时或由其生对应的内存地址都是由编译程序在编译时或由其生成的目标程序运行时进行分配。所以对于编译程序成的目标程序运行时进行分配。所以对于编译程序来说存储组织与管理是一个复杂而又十分重要的问来说存储组织与管理是一个复杂而又十分重要的问题
3、。题。变量及存储空间管理变量及存储空间管理一、一、 目标程序运行时的活动目标程序运行时的活动 一个过程的一个过程的活动活动指的是该过程的一次执行。即每指的是该过程的一次执行。即每次执行一个过程体,就产生该过程的一个活动。次执行一个过程体,就产生该过程的一个活动。 过程过程P P的一个的一个活动的生存期活动的生存期,指的是从执行该过程,指的是从执行该过程体第一步操作到最后一步操作之间的操作序列,包括执体第一步操作到最后一步操作之间的操作序列,包括执行行P P时调用其他过程花费的时间。时调用其他过程花费的时间。一个说明在程序里能起作用的范围称为该说明的一个说明在程序里能起作用的范围称为该说明的作用
4、域作用域。二、二、 活动记录活动记录 为了管理过程在一次执行中所需要的信息,使用一为了管理过程在一次执行中所需要的信息,使用一个连续的存储块,我们把这样的一个连续存储块称为个连续的存储块,我们把这样的一个连续存储块称为活动记录活动记录AR。当前活动记录一般包括如下内容:当前活动记录一般包括如下内容: . 返回地址:返回地址:保存该被调过程返回后的地址。保存该被调过程返回后的地址。 . 动态链(也称控制链或老动态链(也称控制链或老SP):指向调用该过程的那指向调用该过程的那个过程的活动记录地址。个过程的活动记录地址。 . 静态链(或称存取链):静态链(或称存取链):用以存取非局部变量,这些用以存
5、取非局部变量,这些变量存放于其它过程活动记录中。变量存放于其它过程活动记录中。 .形式单元:形式单元:存放相应的实在参数的地址或值。存放相应的实在参数的地址或值。 .局部数据区:局部数据区:局部变量、内情向量、临时工作单元局部变量、内情向量、临时工作单元(如存放对表达式求值的结果)。如图(如存放对表达式求值的结果)。如图三、存储分配模式三、存储分配模式 不同的编译程序关于数据空间的存储分配策略可能不同的编译程序关于数据空间的存储分配策略可能不同。存储分配可采取三种形式:不同。存储分配可采取三种形式:1、静态分配、静态分配 在编译时对所有对象分配固定的存储单元。在编译时对所有对象分配固定的存储单
6、元。且在运行时保持不变。且在运行时保持不变。2、栈式动态分配、栈式动态分配 在运行时把存储器作为一个栈进行管在运行时把存储器作为一个栈进行管理,运行时,每当调用一个过程,它所需要的存储空理,运行时,每当调用一个过程,它所需要的存储空间就动态的分配于栈顶,一旦退出,它所占空间就予间就动态的分配于栈顶,一旦退出,它所占空间就予以释放。以释放。3、堆式动态存储、堆式动态存储 在运行时把存储器组织成堆结构,以在运行时把存储器组织成堆结构,以便用户关于存储空间的申请与归还(回收),凡申请便用户关于存储空间的申请与归还(回收),凡申请者分给一块,凡释放者退回给堆。者分给一块,凡释放者退回给堆。8.1 静态
7、存储分配 如果在编译时就能够确定一个程序在运行时所需的存储空间大小,则在编译时就能够安排好目标程序运行时的全部数据空间,并能确定每个数据项的单元地址,存储空间的这种分配方法叫做静态分配。第八章 运行时存储空间组织 静态存储分配是一种最简单的存储管理。一般而言,适于静态存储分配的语言必须满足以下条件: (1) 数组的上下界必须是常数; (2) 过程调用不允许递归; (3) 不允许采用动态的数据结构(即在程序运行过程中申请和释放的数据结构)。第八章 运行时存储空间组织 满足这些条件的语言有FORTRAN,还有BASIC等语言。在这些语言中,编译程序可以完全确定程序中数据项所在的地址(通常为相对于各
8、数据区起始地址的位移量)。由于过程调用不允许递归,因此数据项的存储地址就与过程相联系。过程调用所使用的局部数据区可以直接安排在过程的目标代码之后,并把各数据项的存储地址填入相关的目标代码中,以便在过程运行时访问这个局部数据区。在此,不存在对存储区的再利用问题;目标程序执行时不必进行运行时的存储空间管理,过程的进入和退出变得极为简单。 第八章 运行时存储空间组织8.2 简单的栈式存储分配 我们首先考虑一种简单程序语言的实现,这种语言没有分程序结构,过程定义不允许嵌套,但允许过程的递归调用,允许过程含有可变数组。例如,C语言除不允许含有可变数组外,就是这样一种语言。C语言的程序结构如下:第八章 运
9、行时存储空间组织 全局数据说明 main() main中的数据说明 void R() R中的数据说明 第八章 运行时存储空间组织 void Q( ) Q中的数据说明 第八章 运行时存储空间组织 例如,下面计算n!的C语言程序就是一个递归调用的程序,它的执行过程可以用栈来实现。 # include “stdio.h” long factorial (int n) if (n1) return (n*factorial (n1); else return (1); 第八章 运行时存储空间组织 main () int num; do scanf (“%d” , &num); if (num=0 &
10、num =0); 第八章 运行时存储空间组织 8.2.1 栈式存储分配与活动记录 使用栈式存储分配法意味着程序运行时,每当进入一个过程(或函数)就有一个相应的活动记录累筑于栈顶,此记录含有连接数据、形式单元、局部变量、局部数组的内情向量和临时工作单元等; 在进入过程和执行过程的可执行语句之前,再把局部数组所需空间累筑于栈顶,从而形成过程工作时的完整数据区。第八章 运行时存储空间组织 注意,每个过程的活动记录的体积在编译时可以静态地确定。但由于允许含有可变数组,所以数组的大小只有在运行时才能知道。因数组区的大小不能预先获知,为了扩充方便,所以只能将数组区累筑于活动记录之上的当前栈顶。当一个过程工
11、作完毕返回时,它在栈顶的数据区(包括活动记录和数组区)也随即不复存在。第八章 运行时存储空间组织 对C语言来说,由于其不含可变数组,因而它的活动记录本身包含了局部数组的空间。图82和图83分别给出了C语言和含可变数组的某简单语言程序运行时的数据空间结构,即显示了主程序在调用了过程Q,Q又调用了过程R,且在R投入运行后的存储结构。 SP指示器总是指向执行过程活动记录的起点,而TOP指示器则始终指向(已占用)栈顶单元。当进入一个过程时,TOP指向为此过程创建的活动记录的顶端;在分配数组区之后(如果有的话),TOP又改为指向数组区(从而是该过程整个数据区)的顶端。第八章 运行时存储空间组织SPTOP
12、R的活动记录Q的活动记录main的活动记录全局数据区第八章 运行时存储空间组织R的数组区R的活动记录Q的数组区Q的活动记录主程序全局数据区TOPSP第八章 运行时存储空间组织 C的活动记录含有以下几个区段(如图84所示): (1) 连接数据(两项):老SP值(即前一活动记录的起始地址)和返回地址; (2) 参数个数; (3) 形式单元(存放实在参数的值或地址); (4) 过程的局部变量(简单变量)、数组的内情向量和临时工作单元。第八章 运行时存储空间组织1TOP临时工作单元内情向量简单变量形式单元参数个数返回地址老SPSP20第八章 运行时存储空间组织 C语言不允许过程(函数)嵌套,也即不允许
13、一个过程的定义出现在另一个过程的定义之内。因此,C语言的非局部变量仅能出现在源程序头,非局部变量可采用静态存储分配并在编译时确定它们的地址。 由图84可知,过程的每一局部变量或形参在活动记录中的位置都是确定的;也就是说,这些变量或形参所分配的存储单元其地址都是相对于活动记录的基址SP的。因此,变量和形参运行时在栈上的绝对地址是: 绝对地址=活动记录基址(SP)+相对地址第八章 运行时存储空间组织 于是,对当前正在执行(即活动)的过程,其任何局部变量或形参X的引用均可表示为变址访问XSP。此处X代表X相对于活动记录基址的偏移量,这个偏移量(即相对数)在编译时可完全确定下来。过程的局部数组的内情向
14、量的相对地址在编译时也同样可完全确定下来,一旦数据空间在过程里获得分配后,对数组元素的引用也就容易用变址的方式进行访问。第八章 运行时存储空间组织 6.2.2 过程的执行 1过程调用 过程调用的四元式序列为: par T1 par T2 par Tn call P,n第八章 运行时存储空间组织 由于此时TOP是指向被调用过程P之前的栈顶,而P的形式单元和活动记录起点之间的距离是确定的(等于3,参见图84),因而由调用者过程给将要调用的过程P的活动记录(正在形成中)的形式单元传递实参值或实参地址,即每个par Ti (i=1,2,n)可直接翻译成如下指令: (i+3)TOP=Ti /*传递参 或
15、 (i+3)TOP=addrTi /*传递参数地址*/第八章 运行时存储空间组织 而四元式call P,n则翻译成: 1TOP=SP /*保护现行SP*/ 3TOP=n /*传递参数个数*/ JSR P /*转子指令,转向P过 程的第 一条指令*/ 过程P调用之前,先构造出P的活动记录部分内容,见图85所示。第八章 运行时存储空间组织参数个数nTOP3SPT2T1现行SP值P的活动记录调用过程TOP43210第八章 运行时存储空间组织 2过程进入 转入过程P后,首先要做的工作是定义新活动记录的SP,保护返回地址和定义新活动记录的TOP值,即执行下述指令: SP= TOP+1 /*定义新SP*/
16、 1SP=返回地址 /*保护返回地址*/ TOP=TOP+L /*定义新TOP*/ 其中,L是过程P的活动记录所需的单元数,这个数在编译时可静态地计算出来。第八章 运行时存储空间组织 对含可变数组(非C语言)的情况来说,因为过程可含可变数组且所有数组都分配在活动记录的顶上,所以紧接上述指令之后应是对数组进行存储分配的指令(如果含有局部数组),这些指令是在翻译数组说明时产生的。对每个数组说明,相应的目标指令组将做以下几件工作: (1) 计算各维的上、下限; (2) 调用数组空间分配子程序,其参数是各维的上、下限和内情向量单元首地址。第八章 运行时存储空间组织 数组空间分配子程序计算并填好内情向量
17、的所有信息,然后在TOP所指的位置之上留出数组所需的空间,并将TOP调整为指向数组区的顶端。进入过程P后所做的工作如图86所示。 此后,在过程段执行语句的工作过程中,凡引用形式参数、局部变量或数组元素都将以SP为基址进行相对访问。第八章 运行时存储空间组织P 的数组区返回地址P的活动记录(长度为L)1调用过程SPTOP0第八章 运行时存储空间组织 3过程返回 C语言以及其它一些相似的语言含有return(E)形式的返回语句,其中E为表达式。假定E值已计算出来并存放在某临时单元T中,则此时即可将T值传送到某个特定的寄存器中(调用过程将从这个特定的寄存器中获得被调用过程P的结果)。剩下的工作就是恢
18、复SP和TOP为进入过程P之前的原值(即指向调用过程的活动记录及工作空间),并按返回地址实行无条件转移,即执行下述指令序列: 第八章 运行时存储空间组织 TOP= SP1 /*恢复调用过程的TOP值*/ SP=0SP /*恢复调用过程的SP值*/ X=2TOP /*将返回地址送X*/ UJ 0X /*无条件转移,即按X的地址返回到调用过程*/ 一个过程也可通过它的end语句(对C语言则是该过程(函数)体结束时的“”)自动返回。如果此过程是一个函数过程,则按上述办法传递结果值,否则仅直接执行上述返回指令序列。过程P的返回示意如图87所示。第八章 运行时存储空间组织SPTOP返回地址老SPP空间调
19、用过程空间第八章 运行时存储空间组织例题与习题解答例题与习题解答1 对于下面程序:对于下面程序: 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. 若参数传递的方法分别为若参数传递的方法分别为 (1)传名()传名(2)传地址)传地址 (3) 传值传值 执行时所输出的执行时所输出的a分别是什么?分别是什么? 解:解: (1)参数传递方法为:传名)参数传递方法为:传名 当执行调用当执行调用p ( a+b, a ,a)时,相当于被调用者被替换成时,相当于被
20、调用者被替换成 procedure p (a+b , a , a) begin a:=a+1 a:=a+a+b end; p 调用者的数据区为:调用者的数据区为: a: 2 b: 3 执行语句执行语句“a:=a+1”后,调用者数据区为:后,调用者数据区为: a: 3 b: 3 执行语句:执行语句:a:=a+a+b 后,调用者的数据区为:后,调用者的数据区为: a: 9 b: 3 因此程序输出为因此程序输出为9。 (2)设参数传递方法为:传地址,)设参数传递方法为:传地址, 则将实在参数的地则将实在参数的地址,传递给调用者址,传递给调用者 p 运行时有(运行时有( 假设假设a的地址为的地址为ad
21、d_a, b的地址为的地址为add_b ); 调用者数据区调用者数据区 被调用者数据区被调用者数据区 add_a: 2 x : T add_b: 3 y : add_a 临时单元临时单元T: 5 z : add_a(a + b)的值的值程序运行执行了语句程序运行执行了语句“y:=y+1”后,有后,有: 调用者数据区调用者数据区 被调用者数据区被调用者数据区 add_a 3 x: T add_b 3 y: add_a 临时单元临时单元T: 5 z: add_a 执行了语句执行了语句“z:=z+x”后有:后有: 调用者数据区调用者数据区 被调用者数据区被调用者数据区 add_a 8 x : T a
22、dd_b 3 y : add_a 临时单元临时单元T: 5 z : add_a所以程序输出所以程序输出 8。 (3)参数传递方法为:)参数传递方法为: 传值传值.则将实参的值传递给被调则将实参的值传递给被调用者用者 p .程序运行时有(假设程序运行时有(假设a的地址为的地址为add_a, b的地址的地址为为 add_b); 调用者数据区调用者数据区 被调用者数据区被调用者数据区 add_a 2 x : 5 add_b 3 y : 2临时单元临时单元T: 5 z : 2程序运行执行了语句程序运行执行了语句“y:=y+1”后有后有: 调用者数据区调用者数据区 被调用者数据区被调用者数据区 add_
23、a 2 x : 5 add_b 3 y : 3临时单元临时单元T: 5 z : 2程序运行执行了语句程序运行执行了语句“z:=z+x”后有后有: 调用者数据区调用者数据区 被调用者数据区被调用者数据区 add_a 2 x : 5 add_b 3 y : 3临时单元临时单元T: 5 z : 7所以程序输出所以程序输出 2。6.3 嵌套过程语言的栈式实现 在简单程序语言实现中是允许过程的递归调用的,并且过程中可含有可变数组。现在,我们再加上一种功能,即允许过程的嵌套性。从结构上看,PASCAL就是这样的一种语言;但由于PASCAL含有“文件”和“动态变量”,因此,它的存储分配不能简单地用栈式方法来
24、实现。采用PASCAL的一个子集,例如去掉“文件”和“动态变量”这种数据类型,那就可以用我们下面将要讨论的方法实现存储分配。第八章 运行时存储空间组织 6.3.1 嵌套层次显示表(DISPLAY)和活动记录 在讨论中,常常要用到过程定义的“嵌套层次”(简称层数)这个概念。我们始终假定主程序的层数为0,因此主程序称为第0层过程。如果过程Q是在层数为i的过程P内定义的,并且P是包围Q的最小过程,则Q的层数就为i+1。当编译程序处理过程说明时,过程的层数将作为过程名的一个重要属性登记在符号表中。第八章 运行时存储空间组织 由于过程定义是嵌套的,因而一个过程可以引用包围它的任一外层过程所定义的变量或数
25、组。也就是说,运行时,一个过程Q可能引用它的任一外层过程P的最新活动记录中的某些数据。因此,过程Q运行时必须知道它的所有外层的最新活动记录的地址。由于允许递归和可变数组的存在,过程的活动记录位置(即使是相对位置)也往往是变迁的,因而必须设法跟踪每个外层过程的最新活动记录的位置。第八章 运行时存储空间组织 一种常用的跟踪每个外层过程最新活动记录位置的有效办法是,每进入一个过程后,在建立它的活动记录区的同时建立一张嵌套层次显示表DISPLAY。假定现在进入的过程层数为i,则它的DISPLAY表含有i+1个单元。此表本身是一个小栈,自顶而下每个单元依次存放着现行层、直接外层直至最外层(第0层,即主程
展开阅读全文