环境管理-编译原理运行时环境 精品
编译原理运行时存储空间的组织和管理课件

变量和数据的存储
• 静态存储:在编译时分配固定大小的内存空间。 • 动态存储:在运行时动态地分配和释放内存空间。 • 数据对齐:为了提高访问效率,对变量在内存中的位置进行调整。 • 在程序中,变量和数据的存储方式通常分为静态存储和动态存储两种。静态存
储是指在编译时就为变量分配固定大小的内存空间,这种方式适用于在程序执 行期间大小不变的变量。而动态存储是在运行时动态地为变量分配和释放内存 空间,它适用于大小在运行时才能确定或者在程序执行过程中会发生变化的数 据结构。为了提高内存访问效率,编译器通常还会进行数据对齐操作,即调整 变量在内存中的位置,使其按照特定的字节边界对齐,这样可以减少CPU访 问内存的次数,提高程序的执行速度。
04 数据段和代码段 的管理
数据段的组织和管理
静态存储分配:在编译时确定变量的 存储空间需求,并为其分配固定的存 储空间。这种分配方式适用于全局变 量和静态变量,其存储空间通常位于 数据段中。
动态存储分配:在运行时根据程序的 需要动态地分配存储空间。这种方式 适用于局部变量和临时变量,其存储 空间通常位于栈或堆中。动态存储分 配能够更有效地利用存储空间,并根 据需要动态调整。
03 堆区和栈区的管 理
堆区的组织和管理
动态内存分配
内存碎片问题
堆区是程序中用于动态内存分配的区 域,使用堆区可以实现在运行时根据 需要动态地分配和释放内存空间。在 堆区中,内存块的大小和数量是灵活 的,可以根据程序的需求进行调整。 常用的动态内存分配函数包括 malloc()和new()。
由于堆区的动态分配特性,频繁地分 配和释放内存块可能会导致内存碎片 问题。内存碎片指的是堆区中无法被 有效利用的小块内存空间。为了解决 这个问题,可以采用内存池技术,预 先分配一大块内存空间,并将其划分 为多个小块,每次需要分配内存时, 从内存池中获取一块合适的内存块。
编译原理教案运行时存储空间经济组织课件

内存生长方向
堆的生长方向向上,即地址由低到高;栈的生长方向向下 ,即地址由高到低。
效率
由于堆需要手动管理,其操作相对复杂,效率较低;栈由 编译器自动管理,操作简便,效率高。
应用场景
堆适用于需要灵活、动态分配内存的场景,如数据结构、 算法等;栈适用于函数调用、局部变量等短暂、固定大小 的内存需求场景。
以上是关于编译原理中运行时存储空间经济组织的课件内容。通过深入了解数据的存储布局 、动态内存分配与管理以及运行时堆的管理策略,可以更好地优化程序的内存使用,提升程 序性能,并减少潜在的内存相关错误。
04
程序执行过程中的内存变化
函数调用与返回时的内存变化
栈帧生成
参数传递
当函数被调用时,会为该函数创建一个栈 帧,用于存储该函数的局部变量、返回地 址以及临时数据。
运行时堆的管理策略
堆的分配策略:堆区通常采用链表、树等数据结构来管理空闲内存块。常见的堆分配策略包 括首次适配(first-fit)、最佳适配(best-fit)和最坏适配(worst-fit)等。
垃圾回收:为了减轻程序员手动管理内存的负担,一些编程语言(如Java和Python)采用 了自动垃圾回收机制。垃圾回收器会定期检测程序中不再被引用的对象,并自动回收其占用 的内存空间。
课程目标和期望
01
02
03
04
知识掌握
深入理解编译原理中各个阶段 ,及它们如何影响存储空间经
济。
能力培养
能够设计和实现具有高效存储 空间管理的编译器。
思维拓展
通过编译原理的学习,培养计 算思维和问题解决能力。
实用技能
掌握一些实用的编译优化技术 和存储空间管理方法。
02
运行时存储空间基础概念
编译原理-运行环境

过程说明语句的翻译
说明语句: Procedure id(X1,X2,…,Xn)
分析参数的类型、分配地址
统计参数和返回值的空间需求 与调用语句配合完成形/实参数的结合
符号表处理
完成过程名的属性登记
过程说明语句代码结构
说明语句: Procedure id(X1,X2,…,Xn) 代码结构 X1.code 按参数传递要求实现参数X1的传递,或者完成传递准备; X2.code 按参数传递要求实现参数X2的传递,或者完成传递准备; …… Xn.code 按参数传递要求实现参数Xn的传递,或者完成传递准备; 完成动态存储分配相关的工作; 进入过程体
主程序 A:=2; B:=3; P(A+B, A, A);
子程序 P(X,Y,Z); {Y:=Y+1;
换名 A:=A+1=3 A:=A+A+B=3+3+3
Print A
Z:=Z+X}
复制恢复:
9
临时单元: T:A+B=5
X=T=5,Y=Z=A=2 Y:=Y+1=3 Z:=Z+X=2+5=7
传地址:
过程调用语句的代码结构
过程调用语句 id(E1,E2, … ,En)
E1.code a1:=E1.place … En.code an:=En.place 动态存储分配相关工作 goto pc+n+1 param a1 … param an call id.place,n
需要一个队列存放a1, a2, …, an,以生成
过程调用的实现
1) 在过程 f 中调用过程 p 时
编译原理-运行环境

03
运行环境概述
操作系统
操作系统是计算机系统的核心软件,负责管理硬 件资源、提供软件运行环境以及执行用户任务。
操作系统的主要功能包括进程管理、内存管理、 文件系统和设备驱动等。
常见的操作系统有Windows、Linux和macOS等。
内存管理
寄存器分配
编译器通过合理地分配寄存器,减少 内存访问次数,提高程序的执行效率。
指令选择
编译器根据目标平台的指令集和特性, 选择最优的指令集来执行程序,以提 高程序的执行效率。
内存管理优化
内存布局优化
编译器可以通过优化内存布局,将相关数据和函数放在一起,减少 内存访问的开销。
内存访问优化
编译器可以通过优化内存访问,减少内存访问次数,提高程序的执 行效率。常见的优化技术包括缓存优化、预取技术等。
保护等。
03
常见的文件系统有FAT32、NTFS和ext4等。
进程与线程管理
进程是操作系统中一个独立运行的程序实例,具有独立的内存空间和系统 资源。
线程是进程中的一个执行单元,共享进程的资源,实现并发执行。
进程与线程管理的主要任务包括进程创建、进程终止、进程切换和线程调 度等。
04
运行环境与编译原理的关系
01 内存管理是操作系统的重要组成部分,负责分配 和回收内存资源。
02 内存管理的主要任务包括内存分配、内存回收、 内存保护和内存扩充等。
03 内存管理算法有静态分配、动态分配和垃圾回收 等。
件系统
01
文件系统是操作系统中用于管理文件存储和访问的机
制。
02
文件系统的主要功能包括文件存储、文件访问和文件
编译原理与技术 运行环境

程序单元的激活(调用)与终止(返回) 程序单元的执行需要:
代码段+活动记录(程序单元运行所需的额 外信息,如参数,局部数据,返回地址等)
2020/2/24
编译原理与技术
运行环境
2020/2/24
《编译原理与技术》-运行环境
1
运行环境
存储组织与分配
程序单元、运行时内存划分与活动记录 静态/动态存储分配 动态栈式的过程调用/返回 非局部名字的访问
参数传递
参数传递的方式及其实现
2020/2/24
《编译原理与技术》-运行环境
2
存储组织与分配
《编译原理与技术》-运行环境
3
运行时内存划分
代码段 静态数据区 栈(stack)
大小可以静态确定 全局/局部静态变量 活动记录栈
堆(heap)
动态分配的数据
2020/2/24
《编译原理与技术》-运行环境
4
活动记录
活动记录-AR (Activation Record) 是一连续存储区域,用于管理与存放和程序 单元执行相关的重要信息。
栈顶sp 临时区
长度可变的区 域放在AR低端
2020/2/24
《编译原理与技术》-运行环境
13
栈式分配下的过程调用与返回
- 过程调用:分配被调过程的AR并填入相关信息, 然后程序控制转移到被调过程入口;
-过程A 调用 过程B 的过程调用序列:
A的“调用”准备操作:1)~ 3)
1)A 计算实在参数并放入(对应栈操作-push) B的活动记录中;(亦可考虑返回值存放空间)
编译原理7 运行环境

d + lR
PROC P PROC Q PROC R
. .引用 Py, Qx
Py Qx
ARR
SP2 SP1 SP0 形式单元 m 全局DISPLAY
lR
d 个单元
返回地址
SP2
老SP Data Section Qx ,内情
.
call call R Q
SP1.2
Q P 形参 n 全局DISPLAY
lQ
TOP 16
主程序P
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
过程 S 过程 Q
SP
i b(形参) 1(形参个数) 0 返回地址 5 i c 0(形参个数) 0 返回地址 0 x a 0 返回地址 0
?第N层过程调用
第 N层过程,如何确 定被调用过程(第 N层) 过程的静态链?
,该函数所需的存储空间动态地分配于栈顶,函 数返回时,释放所占用的空间。
7
Ch6 运行环境
6.1 关于程序运行环境与存储组织
堆式动态存储分配
在内存中开辟一个称为堆的存储区,程序
运行每当需要(申请)时就按照某种分配原则
在堆的自由区(可占用区)中,分配能满足其需
要的存储空间给它,使用后需要释放操作,再
23 22 21 20 19 18 SP 17
d c v(形参) u(形参) 2(形参个数) 11 返回地址 11
动态链
静态链
31
主程序P
16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
过程 S 过程 Q 过程 R 过程 R
TOP 32
31 30 29 28 27 26 SP 25 24 23 22 21 20 19 18 17
编译原理运行时环境

编译原理运行时环境1.内存管理:编译程序在运行过程中需要将源代码转换为目标代码,并将目标代码加载到内存中执行。
为了正确地管理内存空间,运行时环境需要提供内存分配和释放的功能。
通常,运行时环境会分配一块内存区域用于存储程序运行所需的数据和指令。
同时,它还提供内存堆和栈的管理,用于存储程序的动态数据和局部变量。
2.错误处理:编译程序在执行过程中可能会出现各种错误,如语法错误、类型错误、运行时错误等。
运行时环境需要提供错误处理的能力,及时检测和报告程序中的错误。
一般来说,编译程序会将错误信息输出到控制台或者写入日志文件,以便开发人员进行排查和修复。
3.I/O操作:编译程序通常需要进行一系列的输入和输出操作。
例如,解析源代码需要从文件或者标准输入流读取数据,将目标代码写入文件或者标准输出流。
为了完成这些操作,运行时环境需要提供对文件和流的操作支持。
它可以通过打开、关闭、读取和写入等操作,实现与外部环境的数据交换。
4.硬件支持:在编译程序的执行过程中,需要借助硬件设备来进行计算和存储。
运行时环境需要与硬件设备进行交互,获取和发送指令,存储和读取数据。
硬件支持一般包括CPU、内存、硬盘等设备。
5.并发支持:在一些情况下,编译程序可能需要支持并发执行,即同时执行多个任务或线程。
运行时环境需要提供并发支持,包括创建和管理线程、同步和通信机制等。
这样可以充分利用多核处理器的优势,提高程序的执行效率。
总结来说,编译原理运行时环境是编译程序执行过程中的基础设施,为编译程序提供了内存管理、错误处理、I/O操作、硬件支持和并发支持等功能。
它在编译程序执行过程中起到了至关重要的作用,保证了程序的正确运行和高效执行。
同时,不同的编程语言和编译器可能有不同的运行时环境实现方式,但都需要遵循基本的运行时环境规范,以保证程序的正确性和可移植性。
编译原理之运行时刻环境

编译原理之运行时刻环境编译原理是计算机科学中的重要课程,它研究的是将高级语言代码翻译成机器语言的过程。
在编译过程中,除了词法分析、语法分析、语义分析等步骤外,运行时刻环境也是一个非常重要的概念。
本文将介绍编译原理里的运行时刻环境。
什么是运行时刻环境运行时刻环境是指在程序运行过程中支持程序执行的一系列运行时数据结构和服务。
在编译原理中,运行时刻环境通常包含以下几个重要组成部分:1.堆栈(Stack):存储函数调用和局部变量的内存空间。
每个函数调用都会在堆栈上创建一个称为帧的数据结构,用来保存函数参数、局部变量和返回地址等信息。
2.堆(Heap):存储动态分配的内存对象,比如使用new关键字创建的对象会在堆上分配内存。
3.全局数据区(Global Data Area):存储程序运行过程中始终存在的全局变量和静态变量。
4.常量池(Constant Pool):存储程序中使用的常量值,比如字符串、数字等。
5.代码区(Code Area):存储程序的指令集,包括函数的二进制代码等。
运行时刻环境的作用运行时刻环境在程序执行过程中起着至关重要的作用,它主要负责以下几个方面的功能:1.内存管理:运行时刻环境负责内存的分配和释放,保证程序运行时能够动态地分配和释放内存,避免内存泄漏和空指针引用等问题。
2.异常处理:处理程序运行过程中出现的异常情况,比如空指针异常、数组越界异常等,保证程序的稳定性和可靠性。
3.类型检查:在程序运行过程中对数据的类型进行检查,避免类型不匹配导致的错误。
4.动态链接:在程序运行过程中对函数调用进行动态链接,确保程序可以正常调用外部库中的函数。
5.运行时优化:运行时刻环境还可以对程序进行一些优化,比如函数内联、循环展开等,提高程序的执行效率。
运行时刻环境的实现方式不同的编程语言和编译器实现了不同的运行时刻环境,下面以几种常见的实现方式为例进行介绍:JVMJVM(Java Virtual Machine)是Java平台的关键组成部分,它定义了一套独立于硬件平台的指令集架构,并提供了一套丰富的库函数。
编译原理精选全文完整版

可编辑修改精选全文完整版1什么事编译程序?:什么是解解释程序?它们的区别?编译程序就是指这样的一种程序,通过它能够将用高级语言编写的源程序转换成与之在逻辑上等价的低级语言形式的目标程序。
解释程序也是一种翻译程序,它将原程序作为输入,一条语句一条语句地读入并解释执行。
区别:编译程序将源程序翻译成目标程序后在执行该目标程序:解释程序则逐条读出源程序中的语句并解释执行。
2什么是扫描器?:扫描器就是词法分析器,他接受输入的源程序,队源程序进行词法分析并识别出一个个单词符号,其输出结果是单词符号,供语法分析器使用。
通常把此法分析器作为一个子程序,每当词法分析器需要一个单词符号时就调用这个子程序。
每次调用时,词法分析器就从输入串中识别出一个单词符号交给语法分析器。
3.正规表达是到上下无关文法的转换方法是什么?:正规表达式所描述的语言结构均可以用上下文无关文法描述,反之则不一定。
方法如下:1.构造正规表达式的NFA;2.若0为初始状态,则A为开始符号;3.如果存在映射关系f(i,a)=J,则定义产生式Ai→aAj 4. 如果存在映射关系f(i,ξ)=J,则定义产生式Ai→Aj。
5.若1为终态,,则定义产生式Ai→ξ。
4.什么是语法树?:对文法G[s]:(Vt,Vn,S, )满足下列条件的树称为G[s]的语法树。
(1)每个结点用G[s]的一个终结符或非终结符标记。
(2)根据点用文法开始符S标记。
(3)内部结点一定是非终结符,如果某内部结点A有n个分支,它的所有子结点从左至右依次标记为X1,X2,X3……. Xn,则A→X1,X2,X3……. Xn一定是文法G[s]的一条产生式。
(4)如果某节点标记为ξ,则它必为叶结点是父结点的唯一子结点。
5.自下而上分析原理是什么?:自下而上是就是自左至右扫描输入串,自下而上进行分析:通过反复查找当前句型的句柄(最左直接短语),并使用产生式规则将找到的句柄归约为相应的非终结符。
编译原理运行时环境

machunyan
编译原理运行时环境
对名字的访问:(续)
fp mOffset=+8
高端地址
m:2 返回地址
控制链 y:1
mOffset yOffset 低端地址
yOffset=-4
machunyan
编译原理运行时环境
对名字的访问:(续)
例:考虑下面的C过程
对f调用的活动记录为:
Viod f(int x,char c)
编译原理运行时环境
2020/12/13
编译原理运行时环境
第7章 运行时环境(存储空间)(续)
o 存储分配是在运行阶段进行的,但编译程序在 编译阶段要为其设计好存储组织形式,并将这 种组织形式通过生成的目标代码体现出来。 (举例说明:函数调用分析.txt)
o 目标代码运行时,存储空间的组织称为目标代 码的运行时环境。
主调函数的控 制链(main.ebp)
栈底 栈顶
c:3
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
当一个函数被调用时,在栈顶为该函数分配 所需的数据空间(过程活动记录)如下:
1) 将实参的值压入在该函数对应的新活动记录中。 2) 将被调函数执行完毕后的返回地址压入在新的活动记录中。 3) 完成到被调用的过程代码一个转移。 4) 将主调函数的fp作为控制链压入到新的活动记录中。 5) 改变fp以使其指向新的活动记录(将sp复制到fp中) 6) 将该函数的局部变量和局部临时变量压入到新的活动记录中。
放的数据结构 n 过程不可递归调用
machunyan
编译原理运行时环境
7.2 完全静态的运行时环境(续)
整个程序 存储器如 右所示:
编译 第7章 运行时环境

堆管理和完全动态运行时环境
– 堆管理使用 分配操作和释放操作处理指针 分配和重新分配, 这是管理堆的手工方法, 分配和重新分配 这是管理堆的手工方法, 因为程序员必须编写出分配和释放存储器 的明确的调用 – 在一种需要完全动态的运行时环境的语言 中,堆必须自动管理
7.3 参数传递机制
过程活动记录
允许递归调用 – 每一个调用都重新分配局部变量
–
Program main; 全局变量定义; 全局变量定义 Procedure R; … End(R); Procedure Q; … End(Q); 主程序执行体 End.(main)
若主程序调用Q, 递归调用自己 递归调用自己, 若主程序调用 ,Q递归调用自己,在Q 第二次进入运行后的存储结构为: 第二次进入运行后的存储结构为:
i:=5; k[i]:=6; SWAP(i, k[i]);
① 参数传递(add_i 表示 i的地址 参数传递 的地址) 的地址 调用者的数据区 add_i add_K[i] 5 6 被调用者的数据区 add_n add_m add_j ② 过程代码执行后“j:=n;n:=m;m:=j” 过程代码执行后“ 调用者的数据区 add_i add_K[i] 6 5 被调用者的数据区 add_n add_i add_m add_k[i] add_j 结果 :i=6,k[5]=5 ,参数发生改变 , 参数发生改变 5 add_i add_K[i]
代码区 全局变量数据区 全局 静态区 全局/静态区 Main的数据 的数据 Q的数据 的数据 Q的数据 的数据 栈区
3. 完全动态运行时环境
完全动态运行时环境
数据空间在执行时可以任意次地分配与回收。 数据空间在执行时可以任意次地分配与回收。 活动数据仅在对它们所有的引用都消失了才 再重新分配 – 完全动态运行时环境比基于栈的运行环境要 复杂许多, 复杂许多,因为它包含了要在执行时跟踪引 用,以及在执行时任意次地找寻和重新分配 存储器的不可访问区域(这种处理称为垃圾 存储器的不可访问区域(这种处理称为垃圾 回收) 回收)
《编译原理》预备实验五:搭建编译程序集成运行环境框架

预备实验五:搭建编译程序集成运行环境框架实验目的:利用可视化编程工具,搭建编译原理实验的集成运行环境框架。
实验要求:利用自己熟悉的可视化编程工具,搭建自己的可视化程序界面。
实验内容:编写程序,完成如下图所示的编译程序运行界面:主要完成菜单定义和窗口划分。
实验步骤•1、建立应用程序框架–在菜单中选择“文件”—>“新建”打开建立用户应用程序对话框。
–在对话框的“工程”页面左边选择MFCAppWizard[exe];在右边“位置”编辑框中键入要建的项目存放位置,例如D盘根目录;在“工程”编辑框中键入要建的工程名称。
然后确定,进入下一个界面。
•当出现右上图所示的界面时选择“S单个文档”,表示用户程序一次只能打开一个文档窗口;单击“完成”,完成应用程序框架的设计。
•编译连接该应用程序框架,再运行右下图所示。
2 建立自己的MFC菜单项•切换到菜单栏。
切换到资源视图页(ResourceView),双击“Menu”文件夹下的IDR_MAINFRAME,在右边出现菜单栏。
•双击菜单栏上最右边的空白菜单项,弹出菜单项属性对话框。
在标题栏中输入“词法分析”。
•添加下拉菜单项。
在“词法分析”菜单下的空白下拉菜单项处双击鼠标左键。
弹出下拉菜单属性对话框,如下图,设ID为ID_LexAnalyzer,标题为“词法分析器”。
•用同样的方法可以添加多个下拉菜单项。
•建立下拉菜单后,就可以编译运行,运行后在“词法分析”菜单下面的子菜单呈现灰色,点击它却没反应,这是由于还没有对菜单项添加响应消息。
3 为下拉菜单项添加消息响应函数•在菜单编辑界面,鼠标右键单击空白工作区,在弹出菜单中选择“建立类向导”,弹出“建立类向导”MFC ClassWizard对话框。
•在“Class name:”栏选择消息响应函数添加在哪个类中(CMainFrame);在Object IDs中选定需要定义响应函数的对象(ID_LexAnalyzer),在“Messages:”栏选择“COMMAND”表示该消息是命令消息。
环境管理-ch07运行环境 精品

代码区/ 保存目标代码
编译时可以确定代码段的长度, 可以放在一个静态确定的区域内
静态数据区
编译时可确定大小的数据对象,放在静态确 定的区域内,目标地址可以编入目标代码中
控制栈
用于管理过程的活动、 保存断点的现场信息,用于返回时的恢复
???
堆
程序控制下进行的动态存储分配, 分配在堆中,如Pascal中new函数
不能建立动态数据结构
–因为没有在运行时进行存储分配的机制。
19/71
静态存储分配策略的实现
编译器处理声明语句时,每遇到一个变量名就创建一个符号 表条目,填入相应的属性,包括目标地址。
每个变量所需空间的大小由其类型确定,并且在编译时刻是 已知的。
根据名字出现的先后顺序,连续分配空间
name type address ... length 0
过程引用:过程名出现在一个可执行语句中 参数:
–形参、实参
5/71
活动
活动
–一个过程的每次执行称为它的一次活动 –如果一个过程在执行中,则称它的这次活动是活着的
过程与活动
–过程是一个静态概念,活动是一个动态概念 –过程与活动之间可以是1:1、1:m的关系 –递归过程,同一时刻可能有若干个活动是活着的 –每个活动都有自己独立的存储空间/数据空间
活动记录中内容的安排原则
大小能够较早确定的区域放在活动记录的中间, 大小较晚才能确定、并且变化较多的区域放在活 动记录的两头。
–控制链、访问链、机器状态域,是编译器设计的一部分, 编译器构造时就可以确定它们的大小,所以把这些区域 放在活动记录的中间。
–参数域放在前面,便于调用过程进行参数传递,同时, 被调用过程也可很方便地进行访问。
编译原理之运行时刻环境(ppt58张)

栈式分配
• 内容:
–活动树 –活动记录 –调用(代码)序列 –栈中的变长数据
活动树
• 过程调用(过程活动)在时间上总是嵌套的:
–后调用的先返回(LIFO) –因此可以用栈式分配来处理过程活动所需要的内 存空间。
• 程序运行的所有过程活动可以用树表示
–每个结点对应于一个过程活动 –根结点对应于main过程的活动 –过程p的某次活动对应的结点的子结点对应于此次 活动调用的各个过程活动(从左向右,表示调用的 先后顺序)
活动树的例子-快速排序(1)
活动树的例子-快速排序(2)
• 程序:P260,图7-2 • 过程调用(返回)序列和活动 树的前序(后序)遍历对应 • 假定当前活动对应结点N,那 么所有尚未结束的结点对应于 N及其祖先结点。
活动记录
• 过程调用和返回由控制 栈进行管理 • 过程活动记录:当调用 过程或函数时,为其局 部数据动态分配的存储 区 • 活动记录按照活动的开 始时间,从栈底到栈顶 排列
7.3 栈中非局部数据的访问 7.3.1无嵌套过程时的数据访问
• 无嵌套过程时的数据访问
–例:C语言
• 不允许嵌套过程声明,变量要么在函数内定义,要么全局地定 义
–C语言中函数对变量的访问
• 局部变量:在当前活动记录内,可通过top_sp指针加上相对 地址来访问 • 全局/静态变量:在静态区,地址在编译时可知
–p的声明嵌套深度大于q,p必然在q中直接定义,否则 不满足作用域规则,那么p的访问链指向当前活动记录 (即父亲直接调用孩子) –递归调用:p=q 。p的活动记录的访问链等于q当前记 录的访问链(即自身等于自身) –p的声明嵌套深度小于q的深度:此时必然有过程r,p 直接在r中定义,而q嵌套在r中。此时应让p的访问链 指向r的活动记录。(即q是p的侄子系的,r r是p的父亲)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
当源程序的目标代码被运行时,在内存中不 仅有目标代码,而且还要保存各种信息
例如为源程序中出现的一些量(常量、变量及 某些数组等)分配运行时的存储空间。
目标代码要从操作系统得到一块存储区,用 于它的运行。
machunyan
西北工业大学软件与微电子学院
1
第7章 运行时环境(存储空间)(续)
放的数据结构 过程不可递归调用
machunyan
西北工业大学软件与微电子学院
16
7.2 完全静态的运行时环境(续)
整个程序 存储器如 右所示:
machunyan
西北工业大学软件与微电子学院
17
第7章 运行时环境(存储空间)
✓7.1 程序执行时的存储器组织 ✓7.2 完全静态的运行时环境 ✓7.3 基于栈的运行时环境 ▪7.4 动态存储器 ▪7.5 参数存储机制
全程/静态区域:静态数据区用来存放那些具有绝对地 址的数据和变量(如静态变量和全程变量);编译器可 以确定其所占用存储空间的大小,初始化的全局变量 和静态变量在一块区域,未初始化的全局变量和未初 始化的静态变量在相邻的另一块区域,程序执行结束 后由系统释放。
本章案例分析.doc
machunyan
主调函数的控 制链
c:3
栈底 栈顶
machunyan
西北工业大学软件与微电子学院
ห้องสมุดไป่ตู้
14
第7章 运行时环境(存储空间)
✓7.1 程序执行时的存储器组织 ✓7.2 完全静态的运行时环境 ▪7.3 基于栈的运行时环境 ▪7.4 动态存储器 ▪7.5 参数存储机制
machunyan
西北工业大学软件与微电子学院
machunyan
西北工业大学软件与微电子学院
7
7.1程序执行时的存储器组织(续)
堆区:供用户动态申请存储空间,编译器“不需要” 知道究竟得从heap中分配多少空间,也不需要知道从 heap上分配的空间究竟需要存在多久。 在c中由malloc,free运算产生释放的存储空间,在 c++中 由new和delete运算符作用的存储空间,以及 在Java中由new分配的存储空间都在堆中进行分配。
过程的活动记录(activation record,AR)是一段连 续的存储区,用于存放函数的一次执行所需要的信息, 当调用或激活函数时,必须为被调用函数的活动记录 分配空间。
machunyan
西北工业大学软件与微电子学院
11
7.1程序执行时的存储器组织(续)
活动记录存放的信息至少应包括以下几个部分:
西北工业大学软件与微电子学院
6
7.1程序执行时的存储器组织(续)
栈区:函数中的形参和在函数中定义的局部变量以及局 部临时变量(C、C++、Java),这些变量分配在栈区, 每次函数执行的时候会在栈中为函数的执行分配相应的 存储区,而在函数执行完毕后,释放相应的存储区。
编译器“知道”存在栈中的具体数据所占内存大小和内存分配 和释放的“时刻”;
15
7.2 完全静态的运行时环境
在完全静态环境中,不仅全局变量,所有的变量都是 静态分配,即整个程序所需数据空间的总量在编译时 是完全确定的,从而每个数据名的地址就可静态地进 行分配,适于静态分配的语言,要求满足的条件是:
每个数据名所需的存储空间的大小都是常量 不允许采用动态的数据结构,即在程序运行过程中申请或释
运行时环境有三个类型:完全静态环境(fully static environment)、基于栈的环境(stackbased environment),以及完全动态环境(fully dynamic environment)。这3种类型的混合形 式也是可能的。
machunyan
西北工业大学软件与微电子学院
存放主调函数为被调函数 提供的实参信息; 用于指向主调函数的活动记 录的控制链和返回地址;
存放本次执行中的局部数据
存放目标程序临时变 量的值;
machunyan
西北工业大学软件与微电子学院
12
7.1程序执行时的存储器组织(续)
实参
返回地址
调用者
控制链
调
的活动 记录
临时变量和局部数据
用 者
实参 返回地址 控制链
由于栈区和堆区的长 度会随着目标代码的 运行而变化,因此把 它们分配在数据区的 两端。一般情况下, 栈向下长,堆向上长, 可以使栈和堆共用一 空白存储空间。
machunyan
西北工业大学软件与微电子学院
5
7.1程序执行时的存储器组织(续)
代码区域:目标代码的存储区域,由于代码区在执行 之前是固定的,在编译时所有目标代码的地址都是可 计算的,程序执行结束后代码区域内存由系统释放。
3
第7章 运行时环境(存储空间)
✓7.1 程序执行时的存储器组织 ▪7.2 完全静态的运行时环境 ▪7.3 基于栈的运行时环境 ▪7.4 动态存储器 ▪7.5 参数存储机制
machunyan
西北工业大学软件与微电子学院
4
7.1程序执行时的存储器组织
目标代码运行时,操作系统为目标代码的运行分配 的存储空间按用途可划分为下面几个部分:
的
职
被调用
责
者的活
动记录
临时变量和局部数据
machunyan
西北工业大学软件与微电子学院
13
7.1程序执行时的存储器组织(续)
C语言所调用函数 的活动记录示例 (函数调用分析中 的举例)
控制链:指向调 用函数活动记录 的一个地址。
当前函数的 控制链
b:2 a:1 该函数调用结束 时的返回地址 (00401014)
存储分配是在运行阶段进行的,但编译程序在 编译阶段要为其设计好存储组织形式,并将这 种组织形式通过生成的目标代码体现出来。 (举例说明:函数调用分析.txt)
目标代码运行时,存储空间的组织称为目标代 码的运行时环境。
machunyan
西北工业大学软件与微电子学院
2
第7章 运行时环境(存储空间)(续)
machunyan
西北工业大学软件与微电子学院
8
machunyan
西北工业大学软件与微电子学院
9
machunyan
西北工业大学软件与微电子学院
10
7.1程序执行时的存储器组织(续)
在C语言中, 采用以函数(或过程)为单位的动态存 储分配方案:
当一函数被调用时,就在栈顶为该函数分配所需的数据空 间(过程活动记录),当一个函数工作完毕返回时,它在栈 顶的数据空间(过程活动记录)也即释放。