编译原理运行时环境

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

machunyan
编译原理运行时环境
对名字的访问:(续)
fp mOffset=+8
高端地址
m:2 返回地址
控制链 y:1
mOffset yOffset 低端地址
yOffset=-4
machunyan
编译原理运行时环境
对名字的访问:(续)
例:考虑下面的C过程
对f调用的活动记录为:
Viod f(int x,char c)
编译原理运行时环境
2020/12/13
编译原理运行时环境
第7章 运行时环境(存储空间)(续)
o 存储分配是在运行阶段进行的,但编译程序在 编译阶段要为其设计好存储组织形式,并将这 种组织形式通过生成的目标代码体现出来。 (举例说明:函数调用分析.txt)
o 目标代码运行时,存储空间的组织称为目标代 码的运行时环境。
主调函数的控 制链(main.ebp)
栈底 栈顶
c:3
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
当一个函数被调用时,在栈顶为该函数分配 所需的数据空间(过程活动记录)如下:
1) 将实参的值压入在该函数对应的新活动记录中。 2) 将被调函数执行完毕后的返回地址压入在新的活动记录中。 3) 完成到被调用的过程代码一个转移。 4) 将主调函数的fp作为控制链压入到新的活动记录中。 5) 改变fp以使其指向新的活动记录(将sp复制到fp中) 6) 将该函数的局部变量和局部临时变量压入到新的活动记录中。
放的数据结构 n 过程不可递归调用
machunyan
编译原理运行时环境
7.2 完全静态的运行时环境(续)
整个程序 存储器如 右所示:
machunyan
编译原理运行时环境
第7章 运行时环境(存储空间)
7.1 程序执行时的存储器组织 7.2 完全静态的运行时环境 7.3 基于栈的运行时环境 7.4 动态存储器 7.5 参数存储机制
全局/静态区域
main的活动记录
v:10 u:15 返回地址
第一次调用gcd 时的活动记录
main的fp
v:5 u:10 返回地址
第二次调用gcd 时的活动记录
第一次调用gcd时的fp
v:0
u:5
第三次调用gcd
返回地址
时的活动记录
第二次调用gcd时的fp
machunyan
自由空间
栈生长方向 编译原理运行时环境
machunyan
编译原理运行时环境
第7章 运行时环境(存储空间)
7.1 程序执行时的存储器组织 7.2 完全静态的运行时环境 7.3 基于栈的运行时环境 7.4 动态存储器 7.5 参数存储机制
machunyan
编译原理运行时环境
7.1程序执行时的存储器组织
目标代码运行时,操作系统为目标代码的运行分配 的存储空间按用途可划分为下面几个部分:
程序的运行时环境:
{f(y);
x- -;
g(y);
}
}
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
sp,fp
fp sp
sp,fp
fp sp
x:2 x(from f):1
全局/静态区域
m:2 返回地址 main的fp
y:1
main的活动记录
第一次调用g时 的活动记录
n:1
第一次调用f时
machunyan
编译原理运行时环境
machunyan
编译原理运行时环境
machunyan
西北工业大学软件与微电子学院
10 编译原理运行时环境
7.1程序执行时的存储器组织(续)
o 在C语言中, 采用以函数(或过程)为单位的动态存 储分配方案:
n 当一函数被调用时,就在栈顶为该函数分配所需的数据空 间(过程活动记录),当一个函数工作完毕返回时,它在栈 顶的数据空间(过程活动记录)也即释放。
machunyan
编译原理运行时环境
7.2 完全静态的运行时环境
o 在完全静态环境中,不仅全局变量,所有的变量都是 静态分配,即整个程序所需数据空间的总量在编译时 是完全确定的,从而每个数据名的地址就可静态地进 行分配,适于静态分配的语言,要求满足的条件是:
n 每个数据名所需的存储空间的大小都是常量 n 不允许采用动态的数据结构,即在程序运行过程中申请或释
o C语言所调用函数 的活动记录示例 (函数调用分析中 的举例)
o 控制链:指向调 用函数活动记录 的一个地址。
当前函数的 控制链
b:2 a:1 该函数调用结束 时的返回地址 (00401014)
主调函数的控 制链
c:3
栈底 栈顶
machunyan
编译原理运行时环境
第7章 运行时环境(存储空间)
7.1 程序执行时的存储器组织 7.2 完全静态的运行时环境 7.3 基于栈的运行时环境 7.4 动态存储器 7.5 参数存储机制
存放本次执行中的局部数据
存放目标程序临时变 量的值;
machunyan
编译原理运行时环境
7.1程序执行时的存储器组织(续)
实参
返回地址
调用者
控制链

的活动 记录
临时变量和局部数据
用 者
实参 返回地址 控制链


被调用

者的活
动记录
临时变量和局部数据
machunyan
编译原理运行时环境
7.1程序执行时的存储器组织(续)
编译原理)
o 栈区:函数中的形参和在函数中定义的局部变量以及局 部临时变量(C、C++、Java),这些变量分配在栈区, 每次函数执行的时候会在栈中为函数的执行分配相应的 存储区,而在函数执行完毕后,释放相应的存储区。
n 编译器“知道”存在栈中的具体数据所占内存大小和内存分配 和释放的“时刻”;
返回地址
的活动记录
第一次调用g时的fp
m:1 返回地址 第一次调用f时的fp y:0
第二次调用g时的 活动记录
自由空间
machunyan
栈生长方向
编译原理运行时环境
7.3 基于栈的运行时环境(续)
o 目标代码的生成必须
n 支持变量和临时变量的实际定位,并增加支持运 行时环境所必需的代码。
✓ 对名字的访问 • 局部临时变量 • 嵌套声明 • 如何处理可变长度的问题
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
o 目标代码的生成必须
n 支持变量和临时变量的实际定位,并增加支持运 行时环境所必需的代码。
o 对名字的访问 局部临时变量 o 嵌套声明 o 如何处理可变长度的问题
machunyan
编译原理运行时环境
局部临时变量:
o 考虑C表达式:x[i]=(i+j)*(i/k+f(j)),在这个 表达式从左到右的求值计算中,在对f的调 用过程中需要保存中间结果: x[i]的地址、 i+j的和、i/k的商。
o 全程/静态区域:静态数据区用来存放那些具有绝对地 址的数据和变量(如静态变量和全程变量);编译器可 以确定其所占用存储空间的大小,初始化的全局变量 和静态变量在一块区域,未初始化的全局变量和未初 始化的静态变量在相邻的另一块区域,程序执行结束 后由系统释放。
o 本章案例分析.doc
machunyan
machunyan
编译原理运行时环境
对名字的访问:
o 在没有局部过程的基于栈的运行时环境中,所有的非 局部的名字都是全局的,因此也就是静态的,都具有 一个固定的静态地址,可以被直接访问。
o 对函数参数和局部变量而言,在大多数的语言中,如 果函数的声明在编译时是固定的,而且为每个声明分 配的存储器大小也根据其数据类型而固定,每个实参 和局部声明的偏移量可由编译程序计算。
{int a[10];
c
double y;
……
}
fp
x 返回地址 控制链 a[9]
xOffset=+8 aOffset=-40
… a[1]
cOffset=+12 yOffset=-48
a[0]
y
现在对a[i]访问,要求计算地址:
(-40+4*i)(fp)
cOffset xOffset
aOffset yOffset
由于栈区和堆区的长 度会随着目标代码的 运行而变化,因此把 它们分配在数据区的 两端。一般情况下, 栈向下长,堆向上长, 可以使栈和堆共用一 空白存储空间。
machunyan
编译原理运行时环境
7.1程序执行时的存储器组织(续)
o 代码区域:目标代码的存储区域,由于代码区在执行 之前是固定的,在编译时所有目标代码的地址都是可 计算的,程序执行结束后代码区域内存由系统释放。
7.3 基于栈的运行时环境(续)
例:考虑下列程序清单的c代码。
int x=2;
void g(int);
main()
void f(int n) {static int x=1; g(n);
{g(x); return 0;
x- -;
}
}
void g(int m)
画出至第二次对g调用时,
{int y=m-1; if (y>0)
o 过程的活动记录(activation record,AR)是一段连 续的存储区,用于存放函数的一次执行所需要的信息, 当调用或激活函数时,必须为被调用函数的活动记录 分配空间。
machunyan
编译原理运行时环境
7.1程序执行时的存储器组织(续)
o 活动记录存放的信息至少应包括以下几个部分:
存放主调函数为被调函数 提供的实参信息; 用于指向主调函数的活动记 录的控制链和返回地址;
o 2.通过该指针可以访问当前执行函数的实参和局部 变量;
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
void __stdcall f_stdcall(int a,int b)
{ int c; c=a+b;
}
ebp
esp
b:2 a:1 该函数调用结束 时的返回地址 (cs:eip) 00401014
machunyan
编译原理运行时环境
7.1程序执行时的存储器组织(续)
o 堆区:供用户动态申请存储空间,编译器“不需要” 知道究竟得从heap中分配多少空间,也不需要知道从 heap上分配的空间究竟需要存在多久。 n 在c中由malloc,free运算产生释放的存储空间,在 c++中 由new和delete运算符作用的存储空间,以及 在Java中由new分配的存储空间都在堆中进行分配。
machunyan
编译原理运行时环境
第7章 运行时环境(存储空间)(续)
o 运行时环境有三个类型:完全静态环境(fully static environment)、基于栈的环境(stackbased environment),以及完全动态环境(fully dynamic environment)。这3种类型的混合形式 也是可能的。
n 注:用它只可访问栈顶
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
n fp(frame point):控制链指针,即存储当前活 动记录的控制链(即一个地址),对于x86系 统,它采用bp或ebp寄存器存储当前活动记录 的控制链,其作用如下:
o 1.通过该指针可以访问主调函数的活动记录;即允 许在当前的被调函数执行完毕时,用它来恢复主调 函数的活动记录。
当被调函数执行完毕返回时,其对应 的活动记录从栈中弹出的过程:
① 将fp复制到sp中。 ② 将控制链装载到fp中。 ③ 完成到返回地址主调函数的一个转移。 ④ 改变sp以弹出实参。
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
例:计算两个非负整数最大公约数的c代码如下:
#include <studio.h> int x,y; int gcd(int u,int v) { if(v= =0) return u;
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
C语言当前执 行函数的活动 记录示例:
fp sp
b:2 a:1 该函数调用结束 时的返回地址 (cs:eip) 00401014
主调函数的控 制链(main.fp)
c:3
栈底 栈顶
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境
o 在一个所有函数都是全局的、函数定义不允 许嵌套,但允许函数递归调用的程序设计语 言(例如C语言)中,基于栈的动态运行时环 境有两个指针:
n sp:栈顶部(top of stack)指针;对于x86系统来 说,它采用sp或esp寄存器存储栈顶部的地址;
else return gcd(v,u%v) } main() { scanf(“%d%d”,&x,&y);
printf(“%d\n”,gcd(x,y)); return 0;}
machunyan
编译原理运行时环境
7.3 基于栈的运行时环境(续)
sp,fp sp,fp sp,fp sp,fp
x:15 y:10
相关文档
最新文档