编译原理 运行时的存储组织及管理
第七章 运行时的存储组织及管理
文章目录
- 第七章 运行时的存储组织及管理
- 7.1 概述
- 7.2 静态存储分配
- 7.3 动态存储分配
- 7.3.1 活动记录
- 7.3.2 建造display区的规则
- 7.3.3 运行时的地址计算
7.1 概述
运行时的存储组织及管理是目标程序运行时所需要存储空间的组织与管理以及源程序中变量存储空间的分配。
静态存储分配
在编译阶段由编译程序实现对存储空间的管理,和为源程序中的变量分配存储的方法。
条件:如果在编译时能够确定源程序中变量在运行时的数据空间大小,且运行时不改变
但并不是所有数据空间大小都能在编译过程中确定!
动态存储分配
在目标程序运行阶段由目标程序实现对存储空间的组织与管理,和为源程序中的变量分配存储的方法。
特点:在目标程序运行时进行分配;编译时要生成进行动态分配的目标指令。
7.2 静态存储分配
(1)分配策略
由于每个变量所需空间的大小在编译时已知,因此可以用简单的方法给变量分配目标地址。
具体步骤:
- 开辟一数据区。(首地址在加载时确定)
- 按编译顺序给每个模块分配存储。
- 在模块内部按顺序给模块的变量分配存储,一般用相对地址,所占数据区的大小由变量类型确定。
- 目标地址填入变量的符号表中。
这种分配策略要求语言不允许指针或动态分配,不允许递归调用过程(如果递归调用,就相当于又多加了一个函数,又需要分配存储空间了)。典型的例子是Fortran77
(2)模块(fortran子程序)的完整数据区
子程序需要在数据区中保留返回地址,形参也要分配存储以存放相应的实参信息。编译时还要分配临时变量空间(用于存放表达式计算的中间结果等)
FORTRAN子程序的典型数据区:
7.3 动态存储分配
由于编译时还不能具体确定某些数据空间的大小,故对它们分配存储空间必须在程序运行时进行。这时,编译程序生成有关存储分配的目标代码,实际上的分配要在目标程序运行时进行。这种分配方式称为动态存储分配。
对于分程序结构,而且允许递归调用的语言,常使用栈式动态存储分配,即使用一个类似于堆栈的“运行栈”来实现数据区的分配。
分配策略
整个数据区为一个堆栈
- 当进入一个过程时,在栈顶为其分配一个数据区。
- 当退出一个过程时,撤消该过程的数据区。
7.3.1 活动记录
一个典型的活动记录可以分为三部分:
(1)局部数据区:存放模块中定义的各个局部变量
(2)参数区:存放隐式参数(不出现在用户源程序中)和显式参数(出现在用户源程序中)。
形参数据区:每一形参都要分配数据空间,形参单元中存放实参值或者实参地址。
prev abp:存放调用模块记录基地址。该函数执行完时,释放其数据区,数据区指针指向调用前的位置。
ret addr:返回地址,即调用语句的下一条执行指令地址。
ret value :函数返回值(无值则空),比如void函数,就是空的。
(3)display区:存放各外层模块活动记录的基地址。
变量二元地址(BL、ON)
BL:变量声明所在的层次,可以用它找到该层数据区开始地址。此为嵌套层次,并列过程具有相同的层次。
ON:相对于显式参数区开始位置的位移(相对地址)。
例如:
程序模块1:
x(1,0) x在第一层中被声明,在显式参数区开始的位置是0;
y(1,1) NAME(1,2)
过程块M1:
IND(2,0) x(2,1)
注意⚠️:高层(内层)模块可以引用低层(外层) 模块中的变量,例如在M1中可引用外层模块中定义的变量 Y。
在 M1 中引用Y时,可通过其 display 区找到程序块 1 的活动记录基地址,加上 Y 在该数据区的相对地址就可以求得 y 的绝对地址,具体如何引用将在后面提到。
以下是运行栈的跟踪情况:
因此可以画出完整的运行栈图:
(e)当模块4执行完,则abp:=prev abp,这样abp恢复到进入模块4时情况,运行栈情况如©。
(f)当M2执行完,则abp:=prev abp,这样abp恢复到进入模块M2时情况,运行栈情况如(b)。
(g)当M1执行完,则abp:=prev abp,这样abp恢复到进入模块M1时情况,运行栈情况如(a)。
(h)当最外层模块执行完,运行栈恢复到进入模块时的情况,运行栈空。
7.3.2 建造display区的规则
从i层模块进入(调用)j层模块:
(1)若j=i+1
复制i层的display,然后增加一个指向i层模块记录基地址的指针
(第j层模块的display)
(2)若j<=i ,即调用外层模块或同层模块
将i层模块的display区中的前面第j-1个复制到第j层模块的display区
若发生了j>=i+2的情况,例如图中,i想要调用模块k
在这种情况是不行的,因为k的生命周期在j里面。当j执行完后到CALL k后,j(k的外层)生命周期已完结,不能直接调用k。
如果举一个特例的话,如果k中要调用j的变量,如果i直接调用k,那么k将会找不到来自外层的j的变量。
7.3.3 运行时的地址计算
假设要访问的变量的二元地址为:(BL,ON) ,要在LEV层模块中引用BL层模块定义的变量。
如:
在abp(3)引用IND(2,0),会将abp设为display(2),即abp(2),加上display区大小BL-1=1,再加上隐式参数区大小nip=2,与偏移量0,即使IND的地址。
编译原理 运行时的存储组织及管理相关推荐
- 程序运行时的存储组织及管理
目录 程序运行时的存储组织及管理概述 静态存储分配 临时变量的地址分配 简单栈式动态存储 嵌套过程语言的栈式实现 display 表方法 存取链(静态链)方法 参数传递 程序运行时的存储组织及管理概述 ...
- 编译原理--运行时存储组织(自己看)
1. 存储分配的基本概念 1.过程:函数和过程的程序单员 2.过程的活动:程序的一次执行 3.活动记录:一块连续的存储空间,存储过程活动的执行代码和所需信息. 名字.环境.状态.存储单元.值的关系 解 ...
- 编译原理运行时刻环境
编译原理运行时刻环境 运行时存储组织概述 编译程序是将源程序的算法描述部分和数据说明部分,分别翻译成机器目标代码和数据存储单元,最终获得目标程序. 目标程序在目标机环境中运行时,都置身于自己的一个运行 ...
- java运行时_java编译时与运行时概念与实例详解
Java编译时与运行时很重要的概念,但是一直没有明晰,这次专门博客写明白概念. 基础概念 编译时 编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只 ...
- java编译不报错但运行啥都没_java编译时与运行时概念与实例详解
java编译时与运行时概念与实例详解 发布于 2020-7-29| 复制链接 本篇文章通过实例对 java程序编译时与运行时进行了详解,需要的朋友可以参考下 Java编译时与运行时很重要的概念,但是一 ...
- 用scanline取BMP上某点的颜色,代码如下,为什么可以编译,运行时却出错呢?...
用scanline取BMP上某点的颜色,代码如下,为什么可以编译,运行时却出错呢? Delphi / Windows SDK/API http://www.delphi2007.net/DelphiM ...
- Dev C++可以编译但运行时提示Failed to execute且Error 0:操作成功完成。
Dev C++可以编译但运行时提示Failed to execute且Error 0:操作成功完成. 问题 代码 现象 解决办法 更换GCC 可能和杀毒用软件有关系 问题 今天来复习C语言,写了简单几 ...
- [翻译]Go与C#对比 第三篇:编译、运行时、类型系统、模块和其它的一切
Go vs C#, Part 3: Compiler, Runtime, Type System, Modules, and Everything Else | by Alex Yakunin | S ...
- 深入理解JVM底层原理——运行时数据区
运行时数据区概述和线程 1.运行时数据区概述 ! 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行.JVM内存布局规定了Java在运行过程中内存申请 ...
最新文章
- jquery easyui的应用-2
- 【直播回放】150分钟详解模型压缩理论和实践
- Eclipse如何提高开发效率(转)
- 【AI视野·今日CV 计算机视觉论文速览 第196篇】Wed, 12 May 2021
- 【Java习作】KWIC模拟
- 【转载】Eclipse快捷键 10个最有用的快捷键
- rtmp之谷歌浏览器默认启用flash
- ubuntu常见问题有效解决办法
- 69期-Java SE-004_循环、数组-001-002
- Modelsim软件的使用教程
- 【利用FLASH制作交互式课件】
- python制作动态表情包,用 Python 开发一个【GIF表情包制作神器】
- Visual Studio Code下载安装教程
- Springboot定时任务配置及遇到的问题
- 软件企业具体可享受哪些所得税优惠政策?
- 如何快速提升 Flutter App 中的动画性能
- HTTPS安全通信:HTTPS与SSL
- 【转】怎样运行 Vue 打包后的项目
- ID号自动生成,补缺功能
- 【知识总结】分块和值域分块