第七章 运行时的存储组织和分配(2)——存储组织

1、存储组织

1.1、运行时内存的划分

  在运行时,系统将为目标程序分配一块存储空间,这个存储空间按用途可以划分为下面几个部分

( 1 )、目标程序区,用来存放所生成的目标程序;

( 2 )、静态数据区,用来存放编译程序本身就可以确定所占用存储空间大小的数据;

( 3 )、运行栈区,在运行时才能分配存储空间的数据就分配在运行栈;

( 4 )、供用户动态申请存储空间的堆区

这几个部分之间的关系如图7 - 1所示。当然,并不是所有语言的实现都需要这些区域。

                                                            

     图7-1 运行时内存分配示意图

      由于编译程序所生成的目标代码的长度在编译时(至迟在连接之后)就能确定,因此可以把它放在一个静态确定的区域内。同样,若一些数据对象的大小在编译时是已知的,它们也可以放入静态确定的存储区域内。应尽可能多地对数据对象进行静态分配,以缩短运行时间。例如,FORTRAN中的所有数据对象都可以进行静态分配。

      像PASCAL和C 之类语言的实现,则宜于使用扩充的栈来管理过程的活动(我们将一个过程的每一次执行称为这个过程的一次活动)。当出现一个过程调用时,当前正执行的活动将被打断,有关机器状态的信息,如程序计数器的值、返回地址和机器各寄存器的值,应存入栈中。而当控制从一个被调用过程返回时,在恢复了有关寄存器和程序计数器的值之后,被中断的活动将从断点继续执行。

       PASCAL和C 允许数据存储空间在程序控制之下进行分配,这种数据的存储空间可以从堆中得到

       栈和堆可用空白区的大小将随程序的执行而变化。在图7 - 1 中,显示了栈和堆共用一空白存储区,并在使用过程中相互迎面地进行调剂的情况。由于PASCALC既存在过程的递归调用又允许动态申请空间,所以这类语言同时需要运行时的栈和堆

1.2、活动记录

       一个过程的一次执行所需信息的管理,是通过使用一个所谓活动记录的连续存储块来实现的。活动记录中可包括如图7 -2 所示的各个域。在PASCAL和C 语言中,我们通常采用以过程为单位的动态存储分配方案,即当一个过程被调用时,就把它的活动记录推入运行时存储栈的桟顶,而在控制返回调用程序时,再从桟顶弹出相应的活动记录。

 

图7-2 一个常用的活动记录

活动记录中各种域的作用如下:

( 1 )、临时变量域——用来存放目标程序临时变量的值,如计算表达式时所产生的结果;

( 2 )、局部数据域——用来存放过程本次执行中的局部数据、简单变量以及数组内情向量等;

( 3 )、机器状态域——用来保存在调用一个过程之前有关机器状态的信息,其中包括各种寄存器的当前值和返回地址等;

( 4 )、任选的存取链——为访问其它活动记录中所存放的非局部数据提供链地址(这在PASCAL语言中是需要用到的);

( 5 )、任选的控制链——用以指向主调过程的活动记录;

( 6 )、实在参数——用于存放主调过程为被调用过程所提供的实在参数信息(在活动记录中,我们列出了实在参数的存放空间,但是为了提高效率,有时参数是通过机器寄存器来传递的);

( 7 )、返回值域——被调用过程用来为主调过程存放返回值的域。

每个活动记录都可分为定长部分和可变部分定长部分用来存放那些在编译时就能确定其体积的量,如简单变量、常界数组等可变部分用来存放只有在运行时,才能确定其体积的量,如可变数组、动态指针等。虽然只有在运行时,才能为这些可变体积的数据在活动记录的可变部分分配其存储空间,但在编译时却能产生通过活动记录的首地址(一般用一个指示器指示)来访问它们的目标代码,这是因为在该活动记录的定长部分,已设定了存放确定其体积的有关信息的域(如数组的内情向量),而这些域在活动记录中的相对位置是恒定的。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值