BUAACT-Chap06-运行时的存储组织及管理

第六章 运行时的存储组织及管理

6.1 概述

6.1.1 运行时的存储组织及管理

目标程序运行时所需要存储空间的组织与管理以及源程序中变量存储空间的分配。

6.1.2 静态存储分配和动态存储分配

静态存储分配

在编译阶段由编译程序实现对存储空间的管理,和为源程序中的变量分配存储的方法。

条件

如果在编译时能够确定源程序中变量在运行时的数据空间大小,且运行时不改变,那么就可以采用静态存储分配方法。

但是并不是所有数据空间大小都能在编译过程中确定!

动态存储分配

在目标程序运行阶段由目标程序实现对存储空间的组织与管理,和为源程序中的变量分配存储的方法。

特点
  • 在目标程序运行时进行分配。
  • 编译时要生成进行动态分配的目标指令。

6.2 静态存储分配

6.2.1 分配策略

由于每个变量所需空间的大小在编译时已知,因此可以用简单的方法给变量分配目标地址。

  • 开辟一数据区。(首地址在加载时确定)
  • 按编译顺序给每个模块分配存储。
  • 在模块内部按顺序给模块的变量分配存储,一般用相对地址,所占数据区的大小由变量类型确定。
  • 目标地址填入变量的符号表中。

这种分配策略要求语言不允许指针或动态分配,不允许递归调用过程。典型的例子是 Fortran77。

6.3 动态存储分配

由于编译时还不能具体确定某些数据空间的大小,故对它们分配存储空间必须在程序运行时进行。这时,编译程序生成有关存储分配的目标代码,实际上的分配要在目标程序运行时进行。这种分配方式称为动态存储分配。

对于分程序结构,而且允许递归调用的语言,常使用栈式动态存储分配,即使用一个类似于堆栈的“运行栈”来实现数据区的分配。

分配策略

整个数据区为一个堆栈

  • 当进入一个过程时,在栈顶为其分配一个数据区。
  • 当退出一个过程时,撤消该过程的数据区。

6.3.1 活动记录

一个典型的活动记录可以分为三部分:

局部参数区 参数区 display 区

局部参数区

存放模块中定义的各个局部变量。

参数区

存放隐式参数和显式参数。

参数区
参数区
  • prev abp:存放调用模块记录基地址。函数执行完时,释放其数据区,数据区指针指向调用前的位置。
  • ret addr:返回地址,即调用语句的下一条执行指令地址。
  • ret value :函数返回值(无值则空)。
  • 形参数据区:每一形参都要分配数据空间,形参单元中存放实参值或者实参地址。

display 区

存放各外层模块活动记录的基地址。

变量二地址(BL、ON):

  • BL:变量声明所在的层次。可以用它找到该层数据区开始地址。
  • ON:相当于显示参数区开始位置的位移(相对地址)。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BBLOCK;
| REAL X, Y; STRING NAME;
| M1: PBLOCK(INTEGER IND) ;
| (2) INTEGER X;
| | CALL M2 (IND + 1);
| END M1;
(1) M2: PBLOCK(INTEGER J);
| | BBLOCK;
| (3) (4) ARRAY INTEGER F(J);
| | | LOGICAL TESTI;
| | END
| END M2;
| CALL M1(X / Y)
END

程序模块1:

  • x(1, 0)
  • y(1, 1)
  • NAME(1, 2)

过程块 M1:

  • IND(2, 0)
  • x(2, 1)

高层(内层)模块可以引用低层(外层)模块中的变量,例如在M1中可引用外层模块中定义的变量 Y。

在 M1 中引用Y时,可通过其 display 区找到程序块 1 的活动记录基地址,加上 Y 在该数据区的相对地址就可以求得 y 的绝对地址。


BUAACT-Chap06-运行时的存储组织及管理
https://onlyar.site/2022/09/21/BUAACT-Chap06/
作者
Only(AR)
发布于
2022年9月21日
许可协议