06-第6章-运行时存储空间的组织和管理-编译原理-中国科

合集下载

编译原理运行时存储空间的组织和管理课件

编译原理运行时存储空间的组织和管理课件

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

编译原理教案运行时存储空间经济组织课件

编译原理教案运行时存储空间经济组织课件

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

编译原理运行时存储空间经济组织

编译原理运行时存储空间经济组织

《编译原理运行时存储空间经济组织ppt》2023-10-26CATALOGUE目录•编译原理概述•运行时存储空间概述•存储空间的经济组织•存储空间的扩展与维护•编译原理与存储空间的结合应用•总结与展望01编译原理概述1 2 3编译原理是研究如何将高级语言程序翻译成低级语言程序的一门科学。

编译原理定义编译原理关注如何将程序翻译成更低级的语言,以优化程序的运行效率和减小存储空间的使用。

编译原理的关注点编译原理包括词法分析、语法分析、语义分析、优化和代码生成等多个环节。

编译原理的基本组成语法分析根据语言的语法规则,将单词或符号组成语法结构。

词法分析将源程序分解成一个个的单词或符号。

语义分析对语法结构进行语义检查,确保其符合语言的语义规则。

代码生成将优化后的程序翻译成目标机器语言。

优化对已通过语义检查的程序进行优化,以提高程序的运行效率。

编译原理的应用编译器设计编译原理是设计编译器的基础,编译器是实现程序从高级语言到低级语言转换的关键工具。

要点一要点二程序优化利用编译原理中的优化技术,可以提高程序的运行效率,减少存储空间的使用。

语言设计编译原理在语言设计中也有重要的应用,它可以帮助设计者更好地理解语言的语法和语义规则。

要点三02运行时存储空间概述运行时存储空间的概念运行时存储空间指在程序运行过程中,用于存储程序中的变量、函数、类等数据和信息的空间。

运行时存储空间的分类根据存储空间的位置,可以分为内存空间和外存空间。

内存空间包括RAM、Cache等,外存空间包括硬盘、固态硬盘等。

在程序编译时,根据程序中使用的变量、函数、类等信息,分配相应的内存空间。

这种方式适用于程序中数据和函数的使用情况在编译时已知的情况。

在程序运行时,根据实际需要动态地分配内存空间。

这种方式适用于程序中数据和函数的使用情况在编译时无法确定的情况。

静态分配动态分配内存管理单元(MMU)用于管理内存空间的分配和释放。

MMU根据程序的请求,分配相应的内存空间,并在程序结束时释放相应的内存空间。

8hh第6章运行时存储空间组织

8hh第6章运行时存储空间组织
第五页,共41页。
6.1 静态存储分配 6.2 复杂的栈式存储分配 6.3 嵌套进程言语的栈式完成 (wán chéng) 6.4 堆式静态存储分配 6.5 参数传递补遗
第六页,共41页。
6.1 静态存储(cún chǔ)分配
假定编译时能确定顺序运转时所需存储 (cún chǔ)空间的大小, 那么编译时能布置 好顺序运转时的全部数据空间, 并能确定 每个数据项的地址, 这种存储(cún chǔ)分 配FO方RT法R叫AN做言静语态不分允配许。有递归进程,每个数 据名所需存储空间的大小是常量(即不允许 含可变体积的数据), 且一切(yīqiè)数据名 的性质是完全确定的(不允许出现静态确定 其性质的数据名)。故FORTRAN顺序可静 态分配存储空间。
隐 寄存器保护区 参 数 返回地址
图6-1 一个FORTRAN 程序段的局部数据区
隐参数指进程调 用时的衔接信息, 如前往地址、寄 存(jìcún)器维护区 等;
方式单元用来寄 存(jìcún)进程调用 时与形参对应的 实参地址或值。
第十三页,共41页。
6.2 复杂的栈式存储(cún chǔ)分配 首先思索一种复杂顺序文语: 没有分 顺序结构, 进程定义不允许嵌套, 但允 许进程的递归调用, 允许进程含可变数 组。 C言语除了不允许含可变数组外, 就是 (jiùshì)这样一种言语。
现行SP值

SP
P的活动记录 调用过程
图6-5 调用(diàoyòng)进程P之 前先结构P
的活动记载的局部外容 第二十八页,共41页。
2. 进程进入
转入(zhuǎn rù)进程P后, 首先要做的是 定义新活动记载的SP, 维护前往地址和 定义新活动记载的TOP值, 即执行下述指 令:

编译技术-第6章-运行时的存储组织及管理

编译技术-第6章-运行时的存储组织及管理

2 M1: PB2LOCK(INTEGER IND) ;
INTEGER X;
3
CALL M2(IND+1);
7
EDN M1;
3
3 M2: PBLOCK(INTEGER J);
4
4
BBLOCK;
ARRAY INTEGER F(J);
LOGICAL TEST1;
5
END
END M2; 6
AR4 F,TEST1数据区 AR3 参数J AR2 X和参数IND数据区 AR1 X,Y,NAME数据区
分程序结构,且允许递归调用的语言: 栈式动态存储分配
分配策略: 整个数据区为一个堆栈, (1) 当进入一个过程时,在栈顶为其分配一个数据区。 (2) 退出时,撤消过程数据区。
例1:
(1)当进入一个过程时,在栈顶为其分配一个数据区。
(2)退出时,撤消过程数据区。
1
1
BBLOCK;
REAL X, Y; STRING NAME;
MAXPRN RATE IND1 IND2 PRINT YPRINT TOTINT
类型 r r i i r r r
维数 0 0 0 0 1 2 0
地址 264 272 280 284 288 1088 5088
数据区
264 272 280 284 288
+8×100
1088
+8×100×5
5088
(2) 模块(FORTRAN子程序)的完整数据区
变量二元地址(BL、ON) BL:变量声明所在的层次。
可得到该层数据区 开始地址
并列过程具有相同层次
ON:相对于显式参数区的开始位置的位移。
相对地址

《编译原理》教学课件-第6章 运行时存储空间的组织和管理 6-3非局部名字的访问 6-4 参数传递

《编译原理》教学课件-第6章 运行时存储空间的组织和管理 6-3非局部名字的访问 6-4 参数传递

(4)
procedure readarray;
(5)
var i:integer;
(6)
begin ...a... end{readarray};
(7)
procedure exchange(i,j:integer);
(8)
begin
(9)
x:=a[i]; a[i]:=a[j]; a[j]:=x
(10)
被调用过程中的局部名字要保持与调用过程中的名 字不同,因此可以考虑在进行宏扩展以前,将被调 用过程中的每一个名字都系统地给以重新命名
如果需要保持实参的完整性,可以把实参用圆括号 括起来
18
procedure swap(var x, y: integer);
var temp: integer;
begin
3
代码 静态数据

空闲空间
堆 内存区域的典型划分
4
C语言的函数声明不能嵌套,函数不论在什么 情况下激活,要访问的数据分成两种情况:
非静态局部变量(包括形式参数),它们分配 在活动记录栈顶的那个活动记录中
外部变量(包括定义在其它源文件中的外部变 量)和静态的局部变量,它们都分配在静态数 据区
5
指向的那个访问链
14
6.4 参数传递
左值:表达式所表示的存储单元 右值:这个存储单元中所存的值 实参的正文本身
15
6.4.1 值调用
值调用:计算实参,并把实参的右值传给被调 用过程,如C语言
值调用的显著特征是对形参的运算不影响调用 者活动记录中的值
16
6.4.2 引用调用
当参数通过引用(也叫做地址调用或传位置调 用)传递时,调用过程把实参存储单元的地址 传递给被调用过程:

编译原理目标程序运行时的组织

编译原理目标程序运行时的组织

编译原理目标程序运行时的组织简介在编译原理中,目标程序是由程序设计语言的源代码通过编译器转换而成的可执行文件。

目标程序的运行是通过操作系统的支持以及相关的硬件来完成的。

在目标程序运行时,需要对内存的组织进行有效的管理,以保证程序能够正确地执行。

程序的存储结构目标程序在运行时的组织首先涉及到程序的存储结构。

一般来说,目标程序在存储器中被组织为多个段或者区块。

这些段或者区块包括代码段、数据段、堆栈段等。

每个段都有不同的权限,比如代码段通常是只读的,数据段和堆栈段都是读写的。

代码段代码段是存储目标程序的机器指令的区域。

代码段在目标程序运行时是只读的,因为在运行时不能更改源代码。

代码段通常是按照顺序组织的,每条指令都有一个地址。

当程序执行时,计算机会从代码段中读取指令并逐条执行。

数据段数据段是存储目标程序的静态数据、全局变量以及常量的区域。

数据段在目标程序运行时是读写的,因为数据段中的数据可能会发生变化。

数据段通常是按照数据的类型和大小进行组织的,每个数据都有一个地址。

堆栈段堆栈段是存储目标程序的局部变量、函数的参数和返回值等临时数据的区域。

堆栈段在目标程序运行时是读写的,因为堆栈中的数据会被不断压入和弹出。

堆栈段通过栈的数据结构进行组织,数据的压入和弹出都是通过栈指针来实现的。

内存管理目标程序在运行时需要使用内存进行存储和计算。

内存管理是指程序如何分配、使用和释放内存资源的过程。

在目标程序运行时,操作系统负责管理内存的分配和释放,并对内存进行保护,以防止程序的错误操作导致系统崩溃或安全风险。

内存管理的主要任务包括内存分配、内存回收和内存保护。

内存分配是指为程序分配所需的内存空间。

常见的内存分配方式有静态分配和动态分配。

静态分配是在程序加载到内存时预先分配一定的内存空间,而动态分配是根据程序的需要,在运行时临时分配内存空间。

内存回收是指当某个内存空间不再被程序使用时,将其释放回系统。

常见的内存回收方式有手动回收和自动回收。

编译原理运行时存储空间组织

编译原理运行时存储空间组织

主程序P
TOP 4
3
2
1
SP 0
x a 0 返回地址
0
主程序P过程 S
TOP 10
9 8 7 6
SP 5
4 3 2 1 0
动态链
i c 0(形参个数) 0 返回地址
0 x a 0 返回地址
0
?第N层过程调用
第 N+1层过程,如何 确定被调用过程(第 N+1层)过程的静态链?
A:调用过程(第N层
每个过程的活动记录内容如图:
TOP
2 1 SP 0
临时单元 内情向量 局部变量 形式单元 参数个数 返回地址
老SP
对任何局部变量X的 引用可表示为变址访 问:
dx[SP] dx: 变量X相对于活 动记录起点的地址, 在编译时可确定。
9.5 嵌套过程语言的栈式实现
假定语言不仅允许过程的递归调用(和可变 数组),而且允许过程定义的嵌套,如 PASCAL,PL语言。
临时单元 内情向量 局部变量 形式单元
静态链 动态链 返回地址
连接数据
➢返回地址 ➢动态链:指向调用该 过程前的最新活动记 录地址的指针。
➢静态链:指向静态直 接外层最新活动记录 地址的指针,用来访 问非局部数据。
每个过程的活动记录内容
TOP
2 1 SP 0
临时单元 内情向量 局部变量 形式单元
静态链 动态链 返回地址
procedure quicksort(m, n:integer); var i:integer; begin if (n>m) then begin i:=partition(m, n ); quicksort(m, i-1 ); quicksort(i+1, n ) end; end;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• 影响存储分配策略的语言特征
– 过程能否递归 – 当控制从过程的活动返回时,局部变量的值是否
要保留 – 过程能否访问非局部变量 – 过程调用的参数传递方式 – 过程能否作为参数被传递 – 过程能否作为结果值传递 – 存储块能否在程序控制下动态地分配 –存储块是否必理和技术
第六章 运行时存储空间的组织和管理
术语
–过程的活动 过程的一次执行称为过程的一次活动
– 活动记录 过程的活动需要可执行代码和存放所需信息的存 储空间,后者称为活动记录
本章内容 • 讨论一个活动记录中的数据布局 • 程序执行过程中,所有活动记录的组织方式
第六章 运行时存储空间的组织和管理
int a = 0; int b = 0; { / begin of B1 /
int b = 1; {/ begin of B2 /
int a = 2; }/ end of B2 / {/ begin of B3 /
int b = 3; }/ end of B3 / }/ end of B1 / }/ end of B0 /
2、环境和状态
• 环境把名字映射到左值,而状态把左值映射 到右值(即名字到值有两步映射)
• 赋值改变状态,但不改变环境
• 过程调用改变环境
• 如果环境将名字x映射到存储单元s,则说x被
绑定到s
环境
状态
名字
存储单元

6.1 局部存储分配
3、静态概念和动态概念的对应
静态概念 过程的定义
动态对应 过程的活动
6.1 局部存储分配
3、静态概念和动态概念的对应
静态概念 过程的定义 名字的声明
动态对应 过程的活动 名字的绑定
6.1 局部存储分配
3、静态概念和动态概念的对应
静态概念 过程的定义 名字的声明 声明的作用域
动态对应 过程的活动 名字的绑定 绑定的生存期
6.1 局部存储分配
6.1.3 活动记录 活动记录的常见布局
char c1; 0
long i; 4
char c2; 1
char c2; 8
long i; 4
double f; 16
double f; 8
}a;
}b;
对齐:char : 1, long : 4, double : 8
6.1 局部存储分配
• 例 在X86/Linux机器的结果和SPARC/Solaris 工作站不一样,是20和16。
int b = 3; } } }
/ begin of B0 /
/ begin of B1 / / begin of B2 / / end of B2 / / begin of B3 / / end of B3 /
/ end of B1 / / end of B0 /
6.1 局部存储分配
main() / 例 / { / begin of B0 /
typedef struct _a{
typedef struct _b{
char c1; 0
char c1; 0
long i; 4
char c2; 1
char c2; 8
long i; 4
double f; 12
double f; 8
}a;
}b;
对齐:char : 1, long : 4, double : 4
6.1 局部存储分配
• 例 在SPARC/Solaris工作站上下面两个结构 体的size分别是24和16,为什么不一样?
typedef struct _a{
typedef struct _b{
char c1;
char c1;
long i;
char c2;
char c2;
long i;
double f;
字的存储单元 • 介绍三种分配策略
– 静态分配策略 – 栈式分配策略 – 堆式分配策略
6.2 全局栈式存储分配
6.2.1 运行时内存的划分 代码
静态数据 堆

6.2 全局栈式存储分配
1、静态分配 • 名字在程序被编译时绑定到存储单元,不需
要运行时的任何支持 • 绑定的生存期是程序的整个运行期间
6.2 全局栈式存储分配
2、静态分配给语言带来限制 • 递归过程不被允许 • 数据对象的长度和它在内存中位置的限制,
必须是在编译时可以知道的 • 数据结构不能动态建立
6.2 全局栈式存储分配
double f;
}a;
}b;
对齐:char : 1, long : 4, double : 8
6.1 局部存储分配
• 例 在SPARC/Solaris工作站上下面两个结构 体的size分别是24和16,为什么不一样?
typedef struct _a{
typedef struct _b{
char c1; 0
返回值 参数 控制链 访问链 机器状态 局部数据 临时数据
6.1 局部存储分配
6.1.4 局部数据的布局 • 字节是可编址内存的最小单位 • 变量所需的存储空间可以根据其类型而静态
确定 • 一个过程所声明的局部变量,按这些变量声
明时出现的次序,在局部数据域中依次分配 空间 • 局部数据的地址可以用相对于活动记录中某 个位置的地址来表示 • 数据对象的存储布局还有一个对齐问题
6.1 局部存储分配
6.1.5 程序块 • 本身含有局部变量声明的语句 • 可以嵌套 • 最接近的嵌套作用域规则 • 并列程序块不会同时活跃 • 并列程序块的变量可以重叠分配
6.1 局部存储分配
main() / 例 / {
int a = 0; int b = 0; {
int b = 1; {
int a = 2; } {
6.1.1 过程 语言概念:
过程定义、过程调用、形式参数、实在参 数、活动的生存期
6.1 局部存储分配
6.1.2 名字的作用域和绑定 1、名字的作用域 • 一个声明起作用的程序部分称为该声明的作
用域 • 即使一个名字在程序中只声明一次,该名字
在程序运行时也可能表示不同的数据对象
6.1 局部存储分配
声 明 作用域
int a = 0; int b = 0; int b = 1; int a = 2; int b = 3;
B0 B2 B0 B1 B1 B3
B2 B3
a0 b0 b1 a2, b3
重叠分配存储单元
6.2 全局栈式存储分配
本节介绍 • 介绍程序运行时所需的各个活动记录在存储
空间的分配策略 • 描述过程的目标代码怎样访问绑定到局部名
相关文档
最新文档