运行时存储空间的组织和管理教材(PPT 97页).ppt_第1页
运行时存储空间的组织和管理教材(PPT 97页).ppt_第2页
运行时存储空间的组织和管理教材(PPT 97页).ppt_第3页
运行时存储空间的组织和管理教材(PPT 97页).ppt_第4页
运行时存储空间的组织和管理教材(PPT 97页).ppt_第5页
已阅读5页,还剩92页未读 继续免费阅读

下载本文档

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

文档简介

第六章运行时存储空间的组织和管理 编译程序在完成词法 语法和语义分析后 在生成目标代码之前 需要把程序的静态正文和实现这个程序的运行时的活动联系起来弄清楚将来在代码运行时刻 源代码中的各种变量 常量等用户定义的量是如何存放的 如何去访问它们 在程序的执行过程中 程序中数据的存取是通过与之对应的存储单元来进行的 在程序语言中 程序使用的存储单元都是由标识符来表示的 它们对应的内存地址都是由编译程序在编译时或由其生成的目标程序运行时进行分配 所以对于编译程序来说存储组织与管理是一个复杂而又十分重要的问题 本章内容 讨论一个活动记录中的数据安排程序执行过程中 所有活动记录的组织方式存储器的组织与存储分配的策略非局部名称的访问参数传递 6 1局部存储分配策略 过程的每一次运行称为一次活动 activation 活动是一个动态的概念 它有有限的生存期 活动的生存期是指从进入活动的第一条指令执行到离开此活动前的最后一条指令执行的这段时间 其中包括调用其它过程时其它活动的生存期 6 1 2名字的作用域和绑定 名字的作用域一个声明起作用的程序部分称为该声明的作用域 即使一个名字在程序中只声明一次 该名字在程序运行时也可能表示不同的数据对象 名字的绑定运行时为名字X分配存储空间S 这一过程称为绑定 binding 换句话说 绑定是名字X与存储空间S的结合 X是一个对象 既可以是数据对象 如变量 与之结合的是一个存储单元 也可以是操作对象 如过程 与之结合的是可执行的代码 我们的讨论仅限于X是一个数据对象 名字的声明与名字的绑定均需要有对应的存储空间 而存储空间的对应方式 一个是静态的 一个是动态的 声明时关心的是声明的作用域 即当一个名字被引用时 在不同的作用域中与该名字的不同声明结合 绑定时关心的是绑定的生存期 即当一个名字在运行时被实际分配的存储单元 名字与存储单元结合的这段时间被称为绑定的生存期 显然此生存期应该和名字的生存期一致 静态动态过程的定义过程的活动名字的声明名字的绑定声明的作用域绑定的生存期符号表活动记录 静态与动态 变量与值的两步映射 环境改变存储 状态改变值 例5 3若有变量声明x real和常量声明constpi 3 14 则赋值句中变量和常量的映射关系 常量没有左值 存储空间 所以不能被赋值 6 1 3活动记录 为了管理过程在一次执行中所需要的信息 使用一个连续的存储块 我们把这样的一个连续存储块称为活动纪录 返回值 实在参数 控制链 访问链 保存机器状态 局部数据 临时变量 控制链 指向调用过程活动的活动记录 访问链 指向本活动要访问的非局部数据所在的活动记录 保存机器状态 调用过程活动在调用点的机器状态 包括计数器 各种寄存器的值 局部数据 过程中定义的局部量 临时变量 编译产生 6 1 4局部数据的安排字节是可编址内存的最小单位 6 1 4局部数据的安排字节是可编址内存的最小单位 变量所需的存储空间可以根据其类型而静态确定 6 1 4局部数据的安排字节是可编址内存的最小单位 变量所需的存储空间可以根据其类型而静态确定 一个过程所声明的局部变量 按这些变量声明时出现的次序 在局部数据域中依次分配空间 6 1 4局部数据的安排字节是可编址内存的最小单位 变量所需的存储空间可以根据其类型而静态确定 一个过程所声明的局部变量 按这些变量声明时出现的次序 在局部数据域中依次分配空间 局部数据的地址可以用相对于某个位置的地址来表示 6 1 4局部数据的安排字节是可编址内存的最小单位 变量所需的存储空间可以根据其类型而静态确定 一个过程所声明的局部变量 按这些变量声明时出现的次序 在局部数据域中依次分配空间 局部数据的地址可以用相对于某个位置的地址来表示 数据对象的存储安排还有一个对齐问题 6 1 5程序块本身含有局部变量声明的语句可以嵌套最接近的嵌套作用域规则并列程序块不会同时活跃并列程序块的变量可以重叠分配 main beginofB0 inta 0 intb 0 beginofB1 intb 1 beginofB2 inta 2 endofB2 beginofB3 intb 3 endofB3 endofB1 endofB0 main beginofB0 inta 0 intb 0 beginofB1 intb 1 beginofB2 inta 2 endofB2 beginofB3 intb 3 endofB3 endofB1 endofB0 main beginofB0 inta 0 intb 0 beginofB1 intb 1 beginofB2 inta 2 endofB2 beginofB3 intb 3 endofB3 endofB1 endofB0 6 2全局存储分配策略 介绍程序运行时所需的各个活动记录在存储空间的分配策略 6 2全局存储分配策略 介绍程序运行时所需的各个活动记录在存储空间的分配策略描述过程的目标代码怎样访问绑定到局部名字的存储单元 6 2全局存储分配策略 介绍程序运行时所需的各个活动记录在存储空间的分配策略描述过程的目标代码怎样访问绑定到局部名字的存储单元介绍三种分配策略静态分配策略 6 2全局存储分配策略 介绍程序运行时所需的各个活动记录在存储空间的分配策略描述过程的目标代码怎样访问绑定到局部名字的存储单元介绍三种分配策略静态分配策略栈式分配策略 6 2全局存储分配策略 介绍程序运行时所需的各个活动记录在存储空间的分配策略描述过程的目标代码怎样访问绑定到局部名字的存储单元介绍三种分配策略静态分配策略栈式分配策略堆式分配策略 静态分配策略在编译是对所有对象分配固定的存储单元 且在运行是保持不变 栈式动态分配策略在运行时把存储器作为一个栈进行管理 运行时 每当调用一个过程 它所需要的存储空间就动态的分配于栈顶 一旦退出 它所占空间就予以释放 堆式动态存储策略在运行时把存储器组织成堆结构 以便用户关于存储空间的申请与归还 回收 凡申请者分给一块 凡释放者退回给堆 6 2 1运行时内存的划分 6 2 2静态存储分配如果在编译时就能够确定一个程序在运行时所需要的存储空间的大小 则在编译时就能够安排好目标程序运行时的全部数据空间 并能确定每个数据项的单元地址 存储空间的这种分配方法叫做静态分配 特点 绑定是1对1的映射 名字在程序编译时与存储空间结合 每次过程活动时 它的名字映射到同一存储单元 程序运行时不再有对存储空间的分配 静态分配的限制 数据对象的大小和它在内存中位置的限制必须在编译时确定 如数组的大小不能是动态的 不允许程序递归 因为一个过程的所有活动使用同样的名字绑定 即绑定是一对一的 不能动态生成或撤消数据 因为运行时没有存储分配机制 完全采用静态分配的语言 早期的FORTRAN 允许分别编译的数据定义模块 如全程引用的数据 也可以采用静态分配 因为它们一般在整个程序运行的期间是被共享的 6 2 3栈式存储分配存储空间被组织成栈 活动记录的推入和弹出分别对应于活动的开始和结束 与静态分配不同的是 在每次活动中把局部名字和新的存储单元绑定 在活动结束时 活动记录从栈中弹出 因而局部名字的存储空间也随之消失 6 2 3栈式分配活动树 用树来描绘控制进入和离开活动的方式 活动树的特点 每个结点代表某过程的一个活动根结点代表主程序的活动结点a是结点b的父结点 当且仅当控制流从a的活动进入b的活动结点a处于结点b的左边 当且仅当a的生存期先于b的生存期活动树上各节点之间具有下述关系 同一层次的活动生存期不交 任一时刻 处在生存期的活动构成一条从根到某节点的路径 路径上各节点生存期是嵌套的 后进先出 当前活跃着的过程活动可以保存在一个栈中控制栈的内容 s q 1 9 q 1 3 q 2 3 运行栈 把控制栈中的信息拓广到包括过程活动所需的所有局部信息 即活动记录 运行栈 把控制栈中的信息拓广到包括过程活动所需的所有局部信息 即活动记录 s 运行栈 把控制栈中的信息拓广到包括过程活动所需的所有局部信息 即活动记录 运行栈 把控制栈中的信息拓广到包括过程活动所需的所有局部信息 即活动记录 运行栈 把控制栈中的信息拓广到包括过程活动所需的所有局部信息 即活动记录 过程调用和过程返回都需要执行一些代码来管理活动记录栈 保存或恢复机器状态等 过程调用和过程返回都需要执行一些代码来管理活动记录栈 保存或恢复机器状态等过程调用序列过程调用时执行的分配活动记录 把信息填入它的域中的代码 过程调用和过程返回都需要执行一些代码来管理活动记录栈 保存或恢复机器状态等过程调用序列过程调用时执行的分配活动记录 把信息填入它的域中的代码过程返回序列过程返回时执行的恢复机器状态 释放活动记录 使调用过程能够继续执行的代码 过程调用和过程返回都需要执行一些代码来管理活动记录栈 保存或恢复机器状态等过程调用序列过程调用时执行的分配活动记录 把信息填入它的域中的代码过程返回序列过程返回时执行的恢复机器状态 释放活动记录 使调用过程能够继续执行的代码调用序列和返回序列常常都分成两部分 分处于调用过程和被调用过程中 调用者和被调用者之间的任务划分 过程p调用过程q的调用序列p计算实参 依次放入栈顶 并在栈顶留出放返回值的空间 top sp的值在此过程中被改变p把返回地址和当前base sp的值存入q的活动记录中 建立q的访问链 增加base sp的值q保存寄存器的值和其它机器状态信息q根据局部数据域和临时数据域的大小增加top sp的值 初始化它的局部数据 并开始执行过程体 调用者和被调用者之间的任务划分 过程p调用过程q的返回序列q把返回值置入邻近p的活动记录的地方q对应调用序列的步骤 4 减小top sp的值q恢复寄存器 包括base sp 和机器状态 返回pp根据参数个数与类型和返回值类型调整top sp 然后取出返回值 调用者和被调用者之间的任务划分 过程的参数个数可变的情况函数返回值改成用寄存器传递编译器产生将这些参数逆序进栈的代码被调用函数能准确地知道第一个参数的位置被调用函数根据第一个参数到栈中取第二 第三个参数等等 调用者和被调用者之间的任务划分 活动记录的长度在编译时不能确定的情况局部数组的大小要等到过程激活时才能确定在活动记录中为这样的数组分别存放数组指针的单元运行时 这些指针指向分配在栈顶的存储空间 悬空引用 引用某个已被释放的存储单元 悬空引用 引用某个已被释放的存储单元main int dangle int q intj 20 q dangle return 6 3 3堆式存储分配1 局部名的值在活动结束时必须被保存 2 被调用者的活动生存期超过调用者 用活动树不能够正确描绘这种语言的过程之间的控制流 new p dispose p 6 3非局部名字的访问 本节介绍无过程嵌套的静态作用域 C语言 有过程嵌套的静态作用域 Pascal语言 动态作用域 Lisp语言 6 3 1无过程嵌套的静态作用域过程体中的非局部引用可以直接使用静态确定的地址局部变量在栈顶的活动记录中 可以通过base sp指针来访问无须深入栈中取数据 无须访问链过程可以作为参数来传递 也可以作为结果来返回 6 3 2有过程嵌套的静态作用域过程嵌套深度sort1readarray2exchange2quicksort2partition3 6 3 2有过程嵌套的静态作用域过程嵌套深度sort1readarray2exchange2quicksort2partition3变量的嵌套深度 它的声明所在过程的嵌套深度作为该名字的嵌套深度 6 3非局部名字的访问 寻找非局部名字存储单元的访问链 6 3非局部名字的访问 假定过程p的嵌套深度为np 它引用嵌套深度为na的变量a na np 如何访问a的存储单元 sort1readarray2exchange2quicksort2partition3 6 3非局部名字的访问 假定过程p的嵌套深度为np 它引用嵌套深度为na的变量a na np 如何访问a的存储单元 从栈顶的活动记录开始 追踪访问链np na次 6 3非局部名字的访问 假定过程p的嵌套深度为np 它引用嵌套深度为na的变量a na np 如何访问a的存储单元 从栈顶的活动记录开始 追踪访问链np na次 到达a的声明所在过程的活动记录 6 3非局部名字的访问 假定过程p的嵌套深度为np 它引用嵌套深度为na的变量a na np 如何访问a的存储单元 从栈顶的活动记录开始 追踪访问链np na次 到达a的声明所在过程的活动记录 访问链的追踪用间接操作就可完成 6 3非局部名字的访问 访问非局部名字的存储单元 sortreadarrayexchangequicksortpartition 6 3非局部名字的访问 过程p对变量a访问时 a的地址由下面的二元组表示 np na a在活动记录中的偏移 6 3非局部名字的访问 建立访问链假定嵌套深度为np的过程p调用嵌套深度为nx的过程xnp nx的情况sort1readarray2exchange2quicksort2partition3 6 3非局部名字的访问 建立访问链假定嵌套深度为np的过程p调用嵌套深度为nx的过程xnp nx的情况x肯定就声明在p中 6 3非局部名字的访问 建立访问链假定嵌套深度为np的过程p调用嵌套深度为nx的过程xnp nx的情况x肯定就声明在p中被调用过程的访问链必须指向调用过程的活动记录的访问链 6 3非局部名字的访问 建立访问链 sortreadarrayexchangequicksortpartition 6 3非局部名字的访问 建立访问链假定嵌套深度为np的过程p调用嵌套深度为nx的过程xnp nx的情况sort1readarray2exchange2quicksort2partition3 6 3非局部名字的访问 建立访问链假定嵌套深度为np的过程p调用嵌套深度为nx的过程xnp nx的情况p和x的嵌套深度分别为1 2 nx 1的外围过程肯定相同 6 3非局部名字的访问 建立访问链假定嵌套深度为np的过程p调用嵌套深度为nx的过程xnp nx的情况p和x的嵌套深度分别为1 2 nx 1的外围过程肯定相同追踪访问链np nx 1次 到达了静态包围x和p的且离它们最近的那个过程的最新活动记录 6 3非局部名字的访问 建立访问链假定嵌套深度为np的过程p调用嵌套深度为nx的过程xnp nx的情况p和x的嵌套深度分别为1 2 nx 1的外围过程肯定相同追踪访问链np nx 1次 到达了静态包围x和p的且离它们最近的那个过程的最新活动记录所到达的访问链就是x的活动记录中的访问链应该指向的那个访问链 6 3非局部名字的访问 建立访问链 sortreadarrayexchangequicksortpartition 6 3非局部名字的访问 programparam input output 过程作为参数 procedureb functionh n integer integer beginwriteln h 2 end b procedurec varm integer functionf n integer integer beginf m nend f beginm 0 b f end c begincend 6 3非局部名字的访问 programparam input output 过程作为参数 procedureb functionh n integer integer beginwriteln h 2 end b procedurec varm integer functionf n integer integer beginf m nend f beginm 0 b f end c begincend 过程作为参数传递时 怎样在该过程被激活时建立它的访问链 6 3非局部名字的访问 programparam input output 过程作为参数 procedureb functionh n integer integer beginwriteln h 2 end b procedurec varm integer functionf n integer integer beginf m nend f beginm 0 b f end c begincend 过程作为参数传递时 怎样在该过程被激活时建立它的访问链从b的访问链难以建立f的访问链 6 3非局部名字的访问 programparam input output 过程作为参数 procedureb functionh beginwriteln h 2 end procedurec varm integer functionf n integer beginf m nend f beginm 0 b f end c begincend 6 3非局部名字的访问 programret input output 过程作为返回值 varf function integer integer functiona function integer integer varm integer functionaddm n integer integer beginreturnm nend beginm 0 returnaddmend procedureb g function integer integer beginwriteln g 2 end beginf a b f end 6 3非局部名字的访问 programret input output 过程作为返回值 varf function integer integer functiona function integer integer varm integer functionaddm n integer integer beginreturnm nend beginm 0 returnaddmend procedureb g function integer integer beginwriteln g 2 end beginf a b f end 6 3非局部名字的访问 C语言的函数声明不能嵌套 函数不论在什么情况下激活 要访问的数据分成两种情况 非静态局部变量 包括形式参数 它们分配在活动记录栈顶的那个活动记录中外部变量 包括定义在其它源文件中的外部变量 和静态的局部变量 它们都分配在静态数据区 6 3非局部名字的访问 6 3 3动态作用域被调用过程的非局部名字a和它在调用过程中引用的是同样的存储单元 6 3非局部名字的访问 6 3 3动态作用域被调用过程的非局部名字a和它在调用过程中引用的是同样的存储单元 新的绑定仅为被调用过程的局部名字建立 这些名字在被调用过程的活动记录中占用的存储单元 6 3非局部名字的访问 programdynamic input output varr real procedureshow beginwrite r 5 3 end proceduresmall varr real beginr 0 125 showend beginr 0 25 show small writeln show small writelnend 6 3非局部名字的访问 programdynamic input output varr real procedureshow beginwrite r 5 3 end proceduresmall varr real beginr 0 125 showend beginr 0 25 show small writeln show small writelnend 6 3非局部名字的访问 programdynamic input output varr real procedureshow beginwrite r 5 3 end proceduresmall varr real beginr 0 125 showend begin静态作用域r 0 25 0 2500 250show small writeln 0 2500 250show small writelnend 6 3非局部名字的访问 programdynamic input output varr real procedureshow beginwrite r 5 3 end proceduresmall varr real beginr 0 125 showend begin动态作用域r 0 25 0 2500 125show small writeln 0 2500 125show small writelnend 6 3非局部名字的访问 实现动态作用域的方法深访问用控制链搜索运行栈 寻找包含该非局部名字的第一个活动记录浅访问为每个名字在静态分配的存储空间中保存它的当前值当过程p的新活动出现时 p的局部名字n使用在静态数据区分配给n的存储单元 n的先前值可以保存在p的活动记录中 当p的活动结束时再恢复 6 4参数传递 6 4 1值调用实参的右值传给被调用过程值调用可以如下实现把形参当作所在过程的局部名看待 形参的

温馨提示

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

评论

0/150

提交评论