📜  运行时存储

📅  最后修改于: 2020-12-06 08:04:47             🧑  作者: Mango

运行时存储管理

在执行过程中所需的信息保存在称为激活记录的存储块中。激活记录包括存储过程本地名称的信息。

我们可以使用以下方式在目标代码中描述地址:

  • 静态分配
  • 堆栈分配

在静态分配中,激活记录的位置在编译时固定在内存中。

在堆栈分配中,对于过程的每次执行,都会将新的激活记录推入堆栈。激活结束后,将弹出记录。

对于激活记录的运行时分配和取消分配,关联了以下三个地址的语句:

  • 呼叫
  • 返回
  • 停止
  • 动作,其他语句的占位符

我们假设运行时内存分为以下几个区域:

  • 静态数据
  • 叠放

静态分配:

1.通话说明的执行:

需要以下代码来实现静态分配:

MOV #here + 20, callee.static_area     /*it saves return address*/

GOTO callee.code_area /* It transfers control to the target code for the called procedure*/

哪里,

callee.static_area显示激活记录的地址。

callee.code_area显示被调用过程的第一条指令的地址。

#here + 20字面量用于返回GOTO之后的指令地址。

2.执行退货声明:

需要以下代码来实现从过程被调用者的返回:

GOTO * callee.static_area

它用于将控件转移到激活记录开头保存的地址。

3.执行行动说明:

ACTION指令用于实现动作语句。

4.执行暂停声明:

HALT语句是用于将控件返回到操作系统的最终指令。

堆栈分配

使用相对地址,静态分配可以成为堆栈分配,以存储在激活记录中。

在堆栈分配中,寄存器用于存储激活记录的位置,因此可以将激活记录中的字作为对此寄存器中值的偏移量进行访问。

需要以下代码来实现堆栈分配:

1.堆栈初始化:

MOV #stackstart , SP    /*initializes stack*/
HALT                             /*terminate execution*/

2. Call语句的执行:

ADD #caller.recordsize, SP/* increment stack pointer */ 
MOV #here + 16, *SP                  /*Save return address */ 
GOTO callee.code_area

哪里,

caller.recordsize是激活记录的大小

#这里+ 16是GOTO之后的指令地址

3.执行退货声明:

GOTO *0 ( SP ) /*return to the caller */ 
SUB #caller.recordsize, SP           /*decrement SP and restore to previous value */