编译原理-课件chapter9run_第1页
编译原理-课件chapter9run_第2页
编译原理-课件chapter9run_第3页
编译原理-课件chapter9run_第4页
编译原理-课件chapter9run_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2022/8/231Chapter9 Run-Time Environments概 述存储分配策略 (Storage-allocation strategies)访问非局部名字 (Access to nonlocal names)参数传递 (Parameter passing)2022/8/2329.1 概述在生成目标代码之前,必须了解目标代码执行时的环境1、空间环境目标代码的运行都是在操作系统分配的一块存储区内进行的这块存储区必须容纳目标代码和目标代码运行时的数据空间(目标代码中指令能访问的空间)2022/8/2339.1 概述编译程序分配目标程序运行时的数据空间的基本依据是设计程序语言时对

2、程序运行中存储空间的使用和管理办法的规定代码生成器在生成目标代码时必须要体现该程序语言在设计时分配数据空间的规定2022/8/2349.1 概述2、寄存器环境寄存器是目标机器中的宝贵资源如何分配寄存器提高程序运行的效率是代码生成器主要要解决的问题,(详细内容见下一讲)* 数据空间分配和寄存器分配最后都体现在生成的目标代码中2022/8/2359.1 概述几种典型程序设计语言的特点不同的语言有不同的分配数据空间的规定,有不同的组织运行时刻存储空间的方法2022/8/2369.1 概述几种典型程序设计语言的特点与差异:CPASCALALGOLFORTRAN过程递归调用过程嵌套定义动态数组动态内存申

3、请指针检查 2022/8/2379.1 概述名字的联编(Bindings of Names)名字的左值 (l-value) 内存地址,存储名字的瞬时值名字的右值 (r-value) 名字的瞬时值名字的联编 将一个内存地址与一个名字联系起来在程序的一次运行中,一个名字右值(瞬时值)可能会经常改变,一个名字也可能被联编到多个地址(如递归调用中)2022/8/2389.1 概述运行时刻内存的典型划分操作系统收到运行目标程序的指令,分配一块连续的内存空间使目标程序在其上运行P397 Fig7.7这只是一个典型的划分,具体语言不同,该划分也不同栈(Stack):支持过程的递归调用堆(Heap):支持动态

4、内存申请2022/8/2399.1 概述活动记录(Activation Records)是一段连续的存储区,用以存放过程的一次执行所需要的信息,如局部数据活动记录的结构 P398 Fig7.8参数域、状态域、数据域TOP 指向栈顶,TOP-SP 指向局部数据区的开始位置 * 这只是一个一般的结构,具体语言不同,活动记录的结构和内容也有差异2022/8/23109.1 概述过程的活动(Activation)过程的一次完整执行(第一条语句到最后一条语句),称为过程的一次活动过程在执行中称它为活着的如果允许递归调用,程序的一次执行可能有同一个过程的多个实例是活着的* 本章主要讨论不同语言的目标程序在

5、运行时的存储分配策略及名字与其左值和右值的关系2022/8/23119.2 存储分配策略静态存储分配(Static allocation)编译时确定所需的全部数据空间的大小编译时安排好每个名字的存储位置(相对地址)采用静态存储分配的典型语言是 FORTRAN2022/8/23129.2 存储分配策略FORTRAN 语言程序是段结构的,主程序段 + 若干子程序(函数)段没有动态数据类型,每个名字所需空间是确定的没有递归调用,无需栈区没有动态数据结构(如链表),没有动态内存申请,无需堆区2022/8/23139.2 存储分配策略因此,编译时可确定数据区大小,为每个名字分配好地址FORTRAN 程序

6、运行时内存划分为目标代码区和静态数据区,没有栈区和堆区程序例子:P 402 example 7.4Fig.7.10 Fig.7.11 Fig.7.122022/8/23149.2 存储分配策略程序设计语言若允许递归调用、可变数组、可变数据结构:编译时无法确定运行时需要的存储空间大小动态存储分配包括:栈式分配(Stack allocation)和堆式分配(Heap allocation)只能在运行时动态地确定,采用动态存储分配2022/8/23159.2 存储分配策略栈式存储分配的思想:在运行空间中划分一块存储空间作为栈区程序运行时每当调用一个过程,就将该过程的活动记录压入栈中,过程执行完毕将它

7、的活动记录从栈中弹出例子:P405 Fig.7.132022/8/23169.2 存储分配策略栈式存储分配的实现反映在目标代码生成器的构造策略中,最终体现在生成的目标代码中调用序列(Call Sequence)目标代码中的一个指令序列,完成调用一个过程的一系列操作,包括为被调用过程分配一个活动记录,并在相应的域中填入信息2022/8/23179.2 存储分配策略返回序列(Return Sequence)目标代码中的一个指令序列,完成从一个被调用过程返回到它的调用过程的一系列操作,包括释放被调用过程的活动记录,并复制出返回值具体内容:P407 Fig.7.142022/8/23189.2 存储分

8、配策略有些程序设计语言允许用户自由申请内存空间,如 C 的 malloc 和 free,PASCAL 的 new 和 dispose何时申请何时释放由用户决定有些程序设计语言在进行数据空间分配时不服从栈式的存储分配原则(即“先申请后释放、后申请先释放”)2022/8/23199.2 存储分配策略这时采用堆式存储分配方案运行空间划分一块堆区用户(显式)或目标代码需要时从这堆中借用一块,不用时退还* 这是一种完全动态的存储分配方案2022/8/23209.3 访问非局部名字非局部名字相对于引用点所在的过程或分程序来说的程序执行时引用的在当前过程(分程序)之外定义的变量称为非局部名字* 本节主要讨论

9、栈式存储分配中如何访问非局部名字2022/8/23219.3 访问非局部名字最近嵌套的作用域规则 (most closely nested rule)P 412 这是大多数程序设计语言采用的作用域规则例子:P416 Fig.7.22(过程)例子:P413 Fig.7.18(块或分程序)2022/8/23229.3 访问非局部名字分程序(块)结构 ALGOL 和 C分程序(块)含有局部数据说明的语句序列有定界符号,允许嵌套例子:P413 Fig.7.182022/8/23239.3 访问非局部名字过程(活动记录)采用栈式存储分配,分程序中的局部数据在活动记录的局部数据区内也采用栈式分配并列的分程

10、序中的名字可分配同一个地址,因为它们所属的分程序不会在同一时刻存活访问同一过程中的局部名字可以从栈顶到栈底进行定位(同一活动记录中)Fig.7.19* 访问其它过程中的局部名字见下面的讨论2022/8/23249.3 访问非局部名字无过程嵌套定义 C程序中引用的名字或者在当前的过程中被定义,或者在所有过程之外被定义在所有过程之外被定义的变量,称之为全局变量,被存放在静态数据区,地址在编译时刻确定(放符号表中)2022/8/23259.3 访问非局部名字过程中的局部名字联编到过程的活动记录的局部数据区中访问非局部名字可根据符号表中该变量的地址直接到全局静态数据区中查找2022/8/23269.3

11、 访问非局部名字有过程嵌套定义 PASCALPASCAL语言的一个例子 P416过程和函数的嵌套深度(nesting depth)访问非局部名字的方法有两种,一种是通过存取链,一种是通过 DISPLAY 表主程序为 1 2022/8/23279.3 访问非局部名字存取链(access links)活动记录中的一个区,是一个指针若过程 P 直接嵌入在过程 Q 中,则 P 的活动记录中的存取链指向 Q 的最近的活动记录中的存取链2022/8/23289.3 访问非局部名字如何建立存取链?参见 P417 Fig. 7.23(a)(b)(c)(d)区分两种情况: P4181、Np = Nx NpNx+

12、1 2022/8/23299.3 访问非局部名字如何利用存取链访问非局部名字?根据当前过程的嵌套深度和非局部名字所在过程的嵌套深度,可以计算出需顺着存取链前进的步数,从而对非局部名字进行访问 NpNa2022/8/23309.3 访问非局部名字DISPLAY表是一个指向活动记录的指针数组运行时刻要访问的嵌套深度为 i 的非局部名字就在 d i 所指的活动记录中这种方法只要一步就可到达要访问的非局部名字的活动记录,比存取链方法高效2022/8/23319.3 访问非局部名字如何建立与维护 DISPLAY 表?DISPLAY 表的大小由程序中嵌套深度最大的过程决定参见 P421 Fig.7.26

13、(a)(b)(c)(d)2022/8/23329.3 访问非局部名字当建立嵌套深度为 i 的过程的活动记录时,首先在新的活动记录中保存 d i 的值,然后置 d i 指向新的活动记录注意考虑调用和返回两种情况当从过程中返回时,从活动记录中恢复老的 d i 的值2022/8/23339.4 参数传递传值调用(Call-by-Value)把实在参数的右值传递给形式参数调用序列计算实在参数的值,并将它复制到被调用过程活动记录的参数域中这种参数传递方法对调用过程的活动记录没有影响2022/8/23349.4 参数传递引用调用(Call-by-Reference)把实在参数的左值(地址)传递给形式参数调用序列将实在参数的左值(地址)复制到被调用过程活动记录的参数域中被调用过程对形式参数的引用其实是对实在参数的地址(在被调用过程的活动记录中)进行引用2022/8/23359.4 参数传递复制恢复(Copy-Restore)传递参数同传值调用在从被调用过程返回前,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论