目标程序运行时的存储组织课件
合集下载
第10章目标程序运行时的存储组织

p4活动记录 存取链(静态链) 控制链(动态链)
p3活动记录 存取链(静态链) 控制链(动态链)
p3活动记录 存取链(静态链) 控制链(动态链)
main活动记录
2、用Display表
Display表---嵌套层次显示表 当前激活过程的层次为K,它的Display表含有K+1个
单元,依次存放着现行层,直接外层…直至最外层的每 一过程的最新活动记录的基地址。 说明:1、由于过程的层数可以静态确定,因此每个过程 的Display表的体积在编译时即可以确定。
Q的 活动记录
P的 活动记录 主程序的 活动记录
DISPLAY表பைடு நூலகம்维护和建立
为便于组织存储区,将display作为活动记录的一 部分,其相对地址在编译时是完全可以确定的。
假设过程P1可调用P2,为了能在P2中建立P2的 display,在P1调用P2时设法把P1的display地址 作为连接数据之一(全局display地址)传送给P2, 因此连接数据包括: 老SP值(动态链) 返回地址 全局display地址
嵌套过程的栈式分配方案
分程序结构的存储分配方案
3、过程活动:一个过程的活动指的是该过程的一次执行。
4、活动记录:一个过程的一次执行所需要的信息使用一个连 续的存储区来管理,这个区(块)叫做一个活动记录。
活动记录一般包含:
(1)连接数据
返回地址—调用过程指令的下一条指令的地址。
动态链(控制链)—指向调用该过程活动记录地址的指针。用 于当调用返回时,将当前栈顶正确切换到调用者的活动记录
2、某过程p是在层次为i的过程q内定义的,并且q是 包围p的直接外层,那么p的过程层数为i+1。
例: program main(i,0);
p3活动记录 存取链(静态链) 控制链(动态链)
p3活动记录 存取链(静态链) 控制链(动态链)
main活动记录
2、用Display表
Display表---嵌套层次显示表 当前激活过程的层次为K,它的Display表含有K+1个
单元,依次存放着现行层,直接外层…直至最外层的每 一过程的最新活动记录的基地址。 说明:1、由于过程的层数可以静态确定,因此每个过程 的Display表的体积在编译时即可以确定。
Q的 活动记录
P的 活动记录 主程序的 活动记录
DISPLAY表பைடு நூலகம்维护和建立
为便于组织存储区,将display作为活动记录的一 部分,其相对地址在编译时是完全可以确定的。
假设过程P1可调用P2,为了能在P2中建立P2的 display,在P1调用P2时设法把P1的display地址 作为连接数据之一(全局display地址)传送给P2, 因此连接数据包括: 老SP值(动态链) 返回地址 全局display地址
嵌套过程的栈式分配方案
分程序结构的存储分配方案
3、过程活动:一个过程的活动指的是该过程的一次执行。
4、活动记录:一个过程的一次执行所需要的信息使用一个连 续的存储区来管理,这个区(块)叫做一个活动记录。
活动记录一般包含:
(1)连接数据
返回地址—调用过程指令的下一条指令的地址。
动态链(控制链)—指向调用该过程活动记录地址的指针。用 于当调用返回时,将当前栈顶正确切换到调用者的活动记录
2、某过程p是在层次为i的过程q内定义的,并且q是 包围p的直接外层,那么p的过程层数为i+1。
例: program main(i,0);
编译原理第九章 运行时存储空间组织

• 简单栈区(可以带递归,但不可以嵌套定义) • 复杂栈区(可以嵌套定义, pascal)
– 堆区(new, malloc)
9.5 嵌套过程语言的栈式实现
• Pascal 的过程嵌套 嵌套层次:主程序0层 ······ 采用层数计数器,每逢Proc Begin加1,遇 Proc End则减1。
• 直接外层 • 编译器需要将过程的层数记录到符号表中
2)返回函数结果:累加器、寄存器
··· a:= 3 ··· P(a); Write(a); ···
传地址 8,8 8
举例
Procedure P(x) Begin
x:=x+5; writeln(x,a); End;
传结果 8,3 8
传值 8,3 3
举例
begin
Procedure P(x,y,z) …P(a+b,a,a)
初等类型数据采用确定“字长”,数组按列存放,边界对齐。
这样,可将过程活动单元(局部数据区)直接安排在 过程目标码之后,以便运行时访问。
9.3 Fortran静态存储分配(2)
数据区
返回地址 调用程序返回地址(调用恢复地址)
寄存器保护区 保存调用程序的寄存器运行环境
形式单元 形参
简单变量 数组 临时变量
P ->S ->Q =》R ->R
Program P; var a,x…
Top
R
procedure Q(b)
SP
var i…
R
procedure R(u,v)
动
var c,d…
态
begin… R… end {R} 链
Q
begin … R… end{Q} procedure S
– 堆区(new, malloc)
9.5 嵌套过程语言的栈式实现
• Pascal 的过程嵌套 嵌套层次:主程序0层 ······ 采用层数计数器,每逢Proc Begin加1,遇 Proc End则减1。
• 直接外层 • 编译器需要将过程的层数记录到符号表中
2)返回函数结果:累加器、寄存器
··· a:= 3 ··· P(a); Write(a); ···
传地址 8,8 8
举例
Procedure P(x) Begin
x:=x+5; writeln(x,a); End;
传结果 8,3 8
传值 8,3 3
举例
begin
Procedure P(x,y,z) …P(a+b,a,a)
初等类型数据采用确定“字长”,数组按列存放,边界对齐。
这样,可将过程活动单元(局部数据区)直接安排在 过程目标码之后,以便运行时访问。
9.3 Fortran静态存储分配(2)
数据区
返回地址 调用程序返回地址(调用恢复地址)
寄存器保护区 保存调用程序的寄存器运行环境
形式单元 形参
简单变量 数组 临时变量
P ->S ->Q =》R ->R
Program P; var a,x…
Top
R
procedure Q(b)
SP
var i…
R
procedure R(u,v)
动
var c,d…
态
begin… R… end {R} 链
Q
begin … R… end{Q} procedure S
chapter9

编译原理
chapter9
运行时存储空间组织
Chapter9 运行时存储空间组织
编译原理
chapter9
运行时存储空间组织
9.1 目标程序运行时的活动 9.2 运行时存储器的划分 9.3 简单的栈式存储分配 9.4 嵌套过程语言的栈式实现 9.5 堆式动态存储分配
编译原理
chapter9
运行时存储空间组织
9.3 简单的栈式存储分配
编译原理
chapter9
运行时存储空间组织
1. C 的活动记录
TOP
SP
临时工作单元 内情向量 简单变量 形式单元 参数个数 返回地址 老 SP
对任何局部变量或形参的引 用均可表示为: 用均可表示为:X[SP], X表 表 示变量的相对地址. 示变量的相对地址.
相当于动态链
编译程序必须分配目标程序运行时的数据空间. 编译程序必须分配目标程序运行时的数据空间. 9.1 目标程序运行时的活动 1. 过程的活动 过程的每一次运行(或执行 被称为一次活动 过程的每一次运行 或执行)被称为一次活动 或执行 (activation).活动是一个动态的概念,除了设 .活动是一个动态的概念, 计为永不停机的过程(如操作系统等 如操作系统等), 计为永不停机的过程 如操作系统等 ,或者是因 设计错误而出现死循环的过程之外, 设计错误而出现死循环的过程之外,任何过程的 活动均有有限的生存期(life time). 活动均有有限的生存期 .
目标代码 静态数据 栈 ↓ ↑ 堆
过程的活动在编译时 不确定, 不确定,在运行时当 有新过程被调用, 有新过程被调用,则 将该过程的相关数据 放入栈中,栈的life 放入栈中,栈的life 特性正好对应过程的 嵌套调用
chapter9
运行时存储空间组织
Chapter9 运行时存储空间组织
编译原理
chapter9
运行时存储空间组织
9.1 目标程序运行时的活动 9.2 运行时存储器的划分 9.3 简单的栈式存储分配 9.4 嵌套过程语言的栈式实现 9.5 堆式动态存储分配
编译原理
chapter9
运行时存储空间组织
9.3 简单的栈式存储分配
编译原理
chapter9
运行时存储空间组织
1. C 的活动记录
TOP
SP
临时工作单元 内情向量 简单变量 形式单元 参数个数 返回地址 老 SP
对任何局部变量或形参的引 用均可表示为: 用均可表示为:X[SP], X表 表 示变量的相对地址. 示变量的相对地址.
相当于动态链
编译程序必须分配目标程序运行时的数据空间. 编译程序必须分配目标程序运行时的数据空间. 9.1 目标程序运行时的活动 1. 过程的活动 过程的每一次运行(或执行 被称为一次活动 过程的每一次运行 或执行)被称为一次活动 或执行 (activation).活动是一个动态的概念,除了设 .活动是一个动态的概念, 计为永不停机的过程(如操作系统等 如操作系统等), 计为永不停机的过程 如操作系统等 ,或者是因 设计错误而出现死循环的过程之外, 设计错误而出现死循环的过程之外,任何过程的 活动均有有限的生存期(life time). 活动均有有限的生存期 .
目标代码 静态数据 栈 ↓ ↑ 堆
过程的活动在编译时 不确定, 不确定,在运行时当 有新过程被调用, 有新过程被调用,则 将该过程的相关数据 放入栈中,栈的life 放入栈中,栈的life 特性正好对应过程的 嵌套调用
8hh第6章运行时存储空间组织ghs

而P的形式单元与活动记录起点之间的距
离是确定的(等于3), 因而由调用过程给
被调过程P的活动记录(正在形成)的形式
单元传递实参值或实参地址, 即每个par
Ti(i=1,…, n)可直接翻译成如下指令:
(i+3)[TOP]=Ti
//传参数值
或 (i+3)[TOP]=addr[Ti] //参数地址
四元式 call P,n 翻译成:
点, TOP指向为此 过程创建的活动记 录的顶端;
main的数组区
若含有可变数组,
main的活动记录 则 分 配 数 组 区 后 ,
主程序全局数据区 TOP又改为指向数 组区的顶端。
图6-3 含可变数组的程序
的存储组织
C的活动记录含以下几个区段:
(1)连接数据(两项): 老SP值和返回地址, 其中老SP为前一活动记录的起始地址;
SP = TOP+1 //定义新SP 1[SP]=返回地址 //保护返回地址 TOP=TOP+L //定义新TOP 其中L是过程P的活动记录所需的单元 数, 该数在编译时可静态计算出。
对含可变数组的情况, 紧接上述指令 之后是对数组进行存储分配的指令。
对数组进行存储分配的指令是在翻译 数组说明时产生的, 对每个数组说明, 相应的目标指令组将做以下工作:
1[TOP]=SP 3[TOP]=n JSR P
//保护现行SP //传递参数个数 //转向P过程
…
4
TOP+3 3 2
1 0 TOP
T2 T1 参数个数n
现行SP值
…
SP
P的活动记录 调用过程
图6-5 调用过程P之前先构造P 的活动记录的部分内容
操作系统之存储管理

源程序经过汇编或编译后,形成目标程序,每个目标程序都是以 0 为基址顺序进行编址 的,原来用符号名访问的单元用具体的数据——单元号取代。这样生成的目标程序占据一定 的地址空间,称为作业的逻辑地址空间,简称逻辑空间。在逻辑空间中每条指令的地址和指 令中要访问的操作数地址统称为逻辑地址。
一个编译好的程序存在于它自己的逻辑地址空间中,运行时,要把它装入内存空间,图 3.2 显示了一个作业在编译前、编译后及装入内存后不同的地址空间。
1000b 1100b
Mov R1,[1200]
1000b 1100b
Mov R1,[200]
1200b
6817
1200b
6817
1299b
1299b
重定位寄存器
逻辑地址 200b
1000b
1200b 内存地址
(a) 采用静态重定位后的内存空间 (b) 采用动态重定位时内存空间及地址重定位示意图
图 3.3 静态地址重定位和动态地址重定位示意图
静态地址重定位的优点是通过重定位装入程序,实现逻辑地址到物理地址的转化,不需 要硬件的支持,可在任何机器上实现。早期的操作系统中大多数采用这种方法。缺点是程序 必须占用连续的内存空间,且一旦装入内存后,因为逻辑地址已被改变,就不便再移动,不 利于内存空间的利用。所以静态地址重定位只适用于静态的内存分配方式。
⑵ 动态地址重定位 动态地址重定位是在程序执行期间进行的。一般说来,这种转换由专门的硬件机构来完 成,通常采用一个重定位寄存器,在每次进行存储访问时,对取出的逻辑地址加上重定位寄 存器的内容,形成正确的物理地址,重定位寄存器的内容是程序装入内存的起始地址,如图 3.3(b)所示。 动态地址重定位的优点是不要求程序装入固定的内存空间,在内存中允许程序再次移动 位置,而且可以部分地装入程序运行,也便于多个作业共享同一程序的副本,因此,现代计 算机系统广泛采用动态地址重定位技术。动态地址重定位技术缺点是需要硬件支持,而且实
一个编译好的程序存在于它自己的逻辑地址空间中,运行时,要把它装入内存空间,图 3.2 显示了一个作业在编译前、编译后及装入内存后不同的地址空间。
1000b 1100b
Mov R1,[1200]
1000b 1100b
Mov R1,[200]
1200b
6817
1200b
6817
1299b
1299b
重定位寄存器
逻辑地址 200b
1000b
1200b 内存地址
(a) 采用静态重定位后的内存空间 (b) 采用动态重定位时内存空间及地址重定位示意图
图 3.3 静态地址重定位和动态地址重定位示意图
静态地址重定位的优点是通过重定位装入程序,实现逻辑地址到物理地址的转化,不需 要硬件的支持,可在任何机器上实现。早期的操作系统中大多数采用这种方法。缺点是程序 必须占用连续的内存空间,且一旦装入内存后,因为逻辑地址已被改变,就不便再移动,不 利于内存空间的利用。所以静态地址重定位只适用于静态的内存分配方式。
⑵ 动态地址重定位 动态地址重定位是在程序执行期间进行的。一般说来,这种转换由专门的硬件机构来完 成,通常采用一个重定位寄存器,在每次进行存储访问时,对取出的逻辑地址加上重定位寄 存器的内容,形成正确的物理地址,重定位寄存器的内容是程序装入内存的起始地址,如图 3.3(b)所示。 动态地址重定位的优点是不要求程序装入固定的内存空间,在内存中允许程序再次移动 位置,而且可以部分地装入程序运行,也便于多个作业共享同一程序的副本,因此,现代计 算机系统广泛采用动态地址重定位技术。动态地址重定位技术缺点是需要硬件支持,而且实
编译第10章

10.3 栈式存储管理
一、允许过程(函数)递归调用的数据存储管理 1、语言特点 允许过程(函数)的递归调用,但不允许定义嵌套的 过程(函数),也不许使用可变数组。如C语言。 2、栈式存储分配 每进入一个过程,就有相应的数据区建立在栈顶。 当程序开始运行前,用于建造数据区的栈是空栈。当 开始进入主程序执行语句前,便在栈中建立全局变量 和主程序数据区。在主程序中若有调用过程的语句时 ,便在栈顶累筑该过程的活动记录。在进入过程后执 行过程的可执行语句前再把局部数组累筑于栈顶,若 还有调用过程的语句就重复上述过程。
C语言的活动记录
TOP
临时工作单元
内情向量
x
简单变量 形式单元 形参个数 返回地址
2
1
0
老SP
注: 1)活动记录的建立是按照调用次序而累筑,而非排 列次序; 2)栈顶活动记录数据区有两个指针SP和TOP,SP 指向现行数据区起点,TOP指向顶点; 3)从数据区中引出指向主程序数据区的箭头表示外 部变量引用关系;
3. 参数个数和形式单元 4. DISPAY表。 5. 过程所辖的各分程序的局部数据单元。 对于每个分程序来说,它们包括: (1)分程序的TOP值。当进入分程序时它 含现行栈顶地址,以后,用来定义栈的 新高度(分程序的TOP值); (2)分程序的局部变量, 数组内情向量和 临时工作单元。
Procedure A(m,n); integer m,n; B1:begin real z; array B[m:n]; B2:begin real d, e; L3: end; B4:begin array C[1:m]; B5:begin real e; L6: 5 end; end; L8:end;
2 1 4
分程序结构的存储分配方案
Chapter-7-2000

(h)当最外层模块执行完,运行栈恢复到系
18
7.3.2 建造display区的规则
从i层模块进入(调用)j层模块,则: (1)若j=i+1 j i j i 内模块 or call 复制i层的display,然后增加一个指向i层模块记录基地址的指针
但是并不是所有数据空间大小都能在编译过程中确定
3
北京航空航天大学计算机科学与工程系
动态存储分配 在目标程序运行阶段 目标程序实现对存 运行阶段由目标程序 运行阶段 目标程序 储空间的 组织与管理,和为源程序中的 变量 分配存储的方法 特点
• 在目标程序运行时进行分配。 • 编译时要生成进行动态分配的目标指令。
北京航空航天大学计算机科学与工程系
16
数组F TEST1 AR4 J prev abp Ret addr(2) abp(1) AR2 AR1
F的模块 Prev abp
局部数据区
AR3
参数区 abp Display区
Ret addr(3) abp(3) abp(1) AR3 AR2 AR1
参数区
Display区
北京航空航天大学计算机科学与工程系
15
例:下面给出源程序的目标程序运行时,运行栈(数据区栈) 的跟踪情况
NAME AR1 Y X abp 局部数据区
AR2
X IND prev abp Ret addr(1) abp(1) AR1
局部数据区
参数区 Display区
abp
(a)进入模块1
(b)M1被调用
北京航空航天大学计算机科学与工程系
11
7.3.1 活动记录
一个典型的活动记录可以分为三部分:
局部数据区 参数区 display区 (1)局部数据区:
程序运行时的存储组织方式

程序运行时的存储组织方式通常包括以下几个部分:
代码区:也称为文本区或代码段,用于存放程序的二进制代码。
这部分通常只读,以防止程序在运行时被修改。
数据区:用于存放静态变量和全局变量。
这些变量在程序的生命周期内保持不变。
堆:用于动态分配内存。
当程序运行时,如果需要动态分配内存,比如为数组或结构体分配内存,那么会从堆中分配。
当不再需要这些内存时,通常会手动释放这些内存,以便让系统可以重用这些资源。
栈:用于存放局部变量和函数调用的信息。
每当一个函数被调用时,它的参数、返回地址和局部变量都会被压入栈中。
当函数返回时,这些信息会被从栈中弹出。
其他数据结构:根据程序的需要,还可能使用其他的数据结构来存储和管理数据,比如队列、链表、哈希表等。
这种存储组织方式有助于提高程序的效率和安全性。
例如,代码区只读可以防止恶意代码的注入;数据区和堆的分离可以防止内存泄漏;栈的自动管理可以减少内存管理的复杂性;而其他数据结构则可以根据需要灵活地存储和管理数据。