编译原理与技术
编译原理 编译的过程
编译原理编译的过程
编译原理是计算机科学与技术领域的一个重要学科,它研究的是将高级程序语言转化为机器语言的过程,以实现程序的运行。编译的过程可以分为以下几个步骤。
1. 词法分析(Lexical Analysis):将输入的源代码序列划分为
一个个的词素(Token),并对每个词素进行分类。
2. 语法分析(Syntactic Analysis):根据语法规则,利用词法
分析得到的词法单元序列,生成抽象语法树(Abstract Syntax Tree),以表达程序的结构。
3. 语义分析(Semantic Analysis):对生成的抽象语法树进行
语义的验证,包括类型检查、作用域检查等。同时,将高级语言的语句转化为中间代码表示。
4. 优化(Optimization):对生成的中间代码进行优化,以提
高程序的执行效率。包括常量折叠、公共子表达式消除、循环优化等。
5. 中间代码生成(Intermediate Code Generation):将优化后
的中间代码转化为目标机器独立的中间代码表示,如三地址码、虚拟机指令等。
6. 目标代码生成(Code Generation):根据目标机器的特点,
将中间代码转化为目标机器代码,如汇编语言代码或机器指令。
7. 目标代码优化(Code Optimization):对生成的目标代码进行优化,以进一步提高程序的执行效率。
8. 目标代码的链接与装载(Linking and Loading):将编译得到的目标代码与库进行链接,生成可执行程序,并将其加载到内存中执行。
编译过程中的每个阶段都具有特定的功能和任务,它们相互协作,最终将高级语言的源代码转化为目标机器可执行的代码。这个过程可以分为前端和后端两个部分,前端主要负责语法和语义分析等,后端主要负责中间代码的生成、目标代码生成和优化等。编译过程需要充分考虑程序的正确性、效率和可维护性等方面的要求。
编译原理技术和工具
编译原理技术和工具
编译原理技术和工具是计算机科学领域中的重要研究方向,它研究的是将高级程序语言转换为可执行代码的过程。在软件开发中,编译器起着至关重要的作用,它能够将人类可读的程序代码转换为计算机可执行的指令,从而使得计算机能够理解和执行这些代码。本文将介绍编译原理技术的基本概念和常用的工具,以及它们在软件开发中的应用。
一、编译原理技术的基本概念
1. 词法分析:词法分析是编译过程的第一步,它将源代码分割成一个个的词法单元。词法单元是源代码中的最小语法单位,如关键字、标识符、常量等。词法分析器根据预先定义的词法规则,将源代码分割成词法单元序列,以供后续的语法分析使用。
2. 语法分析:语法分析是编译过程的第二步,它根据词法分析器产生的词法单元序列,构建抽象语法树。抽象语法树是源代码的一种树形表示,它反映了源代码的语法结构。语法分析器根据预先定义的语法规则,将词法单元序列组织成抽象语法树,以供后续的语义分析和代码生成使用。
3. 语义分析:语义分析是编译过程的第三步,它对抽象语法树进行静态检查和语义处理。语义分析器主要检查源代码是否符合语言规范,并对源代码进行类型检查和语义推导等处理。语义分析器通过
遍历抽象语法树,对每个节点进行相应的语义处理,以保证生成的目标代码具有正确的语义。
4. 代码生成:代码生成是编译过程的最后一步,它将经过语义分析的抽象语法树转换为目标代码。代码生成器根据目标机器的特性和约束,将抽象语法树转换为目标代码的中间表示形式,然后再将中间表示形式转换为目标机器的机器代码。代码生成器的优化算法可以对中间表示形式进行优化,以提高生成的目标代码的效率和质量。
全国各院校计算机科学与技术考研考试科目汇总表
全国各院校计算机科学与技术考研考试科目汇总表
以下是全国各院校计算机科学与技术考研考试科目的汇总表:
1. 数据结构与算法分析:该科目主要测试考生对于数据结构和算法的理解和应用能力。包括常见数据结构(如树、图、堆、队列等)、排序算法、查找算法等的掌握程度。
2. 计算机网络:该科目主要考察考生对计算机网络原理、协议、路由、网络安全等方面的了解。包括网络结构、网络协议、网络通信等内容。
3. 操作系统:该科目主要考察考生对操作系统的概念、原理、调度、存储管理等方面的理解和掌握程度。包括进程管理、内存管理、文件系统等内容。
4. 数据库原理与应用:该科目主要考察考生对于数据库的基本原理、数据库设计、SQL语言等方面的理解和应用能力。包
括关系数据库模型、数据库设计范式、数据库查询等内容。
5. 编译原理与技术:该科目主要考察考生对编译原理、编译器构造和相关技术的了解。包括词法分析、语法分析、语义分析、代码优化等内容。
6. 软件工程与软件开发:该科目主要考察考生对于软件工程和软件开发的基本原理和方法的理解和应用能力。包括软件需求分析、软件设计、软件测试、软件项目管理等内容。
除了以上常见的科目,不同院校的考研科目可能会有所不同,具体以各院校的招生信息为准。同时,考研科目的内容和难度也会因不同院校而有所差异,考生应及时了解并做好准备。
编译原理与优化技术
编译原理与优化技术
编译原理和优化技术是计算机科学中的两个核心领域,它们对于程序的性能和效率有着重要的影响。在本文中,我们将探讨编译原理与优化技术的相关概念、原理和应用。
一、编译原理概述
编译原理是研究如何将高级程序语言翻译成为机器语言的科学。编译器是实现这一任务的工具,它能够将程序源代码翻译成为可执行的目标代码,并具备不同的优化策略。编译原理主要包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等多个阶段。
词法分析的目的是将源代码分解成为有意义的单词或符号,例如标识符、关键字、数值等。语法分析则将这些单词或符号组织成为语法正确的结构,通过构建语法树来表示程序的结构。语义分析阶段是在语法树的基础上,进一步检查程序的语义是否合理,例如变量是否被声明、运算是否合法等。
中间代码生成阶段将语法树转换为中间表示形式,以便进行后续的优化和目标代码生成。代码优化是编译器的一个重要任务,它通过对程序进行静态分析,找到可以改进程序性能的机会,并对代码进行重构和改进。目标代码生成将中间表示形式转化为机器代码,使程序最终能够在计算机上执行。
二、常见的优化技术
1. 代码优化
代码优化是编译器中最关键的一环,它能够对程序进行静态分析,发现性能瓶颈,并进行相应的改进。常见的代码优化技术包括常量传播、循环展开、死代码删除、公共子表达式消除等。通过这些技术,编译器可以将性能较差的代码转化为更加高效的形式,从而提升程序的执行速度。
2. 数据流分析
数据流分析是一种通过分析程序中数据的变化情况来推测程序行为的技术。在
编译原理技术和工具
编译原理技术和工具
编译原理是计算机科学中的一个重要分支,它研究的是如何将高级语言转换成机器语言。编译原理技术和工具是编译器开发中必不可少的一部分,它们可以帮助开发人员更快、更准确地开发出高质量的编译器。
编译原理技术包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等。其中,词法分析和语法分析是编译器开发中最基础的技术。词法分析器负责将源代码转换成一个个单词,而语法分析器则负责将单词组合成语法树。语义分析器则负责检查语法树是否符合语义规则,中间代码生成器将语法树转换成中间代码,代码优化器则负责对中间代码进行优化,目标代码生成器则将中间代码转换成机器代码。
编译原理工具包括Lex、Yacc、Bison、LLVM等。Lex是一个词法分析器生成器,它可以根据用户定义的正则表达式生成词法分析器。Yacc和Bison是语法分析器生成器,它们可以根据用户定义的文法生成语法分析器。LLVM是一个开源的编译器基础设施,它提供了一个中间代码表示,可以用于生成目标代码。
使用编译原理技术和工具可以帮助开发人员更快、更准确地开发出高质量的编译器。例如,使用Lex和Yacc可以快速生成词法分析器和语法分析器,大大减少了开发时间。使用LLVM可以将中间代码
转换成多种目标代码,提高了编译器的可移植性和性能。
编译原理技术和工具是编译器开发中必不可少的一部分,它们可以帮助开发人员更快、更准确地开发出高质量的编译器。在未来,随着计算机科学的不断发展,编译原理技术和工具也将不断更新和完善,为编译器开发提供更加强大的支持。
编译原理与技术 文法和分析(1)
S⇒AB
S A B
⇒aAB
A a A
⇒aaAB
A a A
⇒aaaB
A a
⇒aaabB
B b B
⇒aaabb
B b
2024/7/8
《编译原理与技术》讲义
22
e.g.5 文法产生的语言
文法G5对句子aaaabbbb的推导:
S⇒aSb
S a S b
⇒aaSbb
S a S b
⇒aaaSbbb
S a S b
x= x ✓串的前缀- 任意串x,从其第一个字符(最左字符)
起的字符序列是其前缀。亦是。 e.g. x = abc, 则,a,ab,abc均是x的前缀
2024/7/8
《编译原理与技术》讲义
3
若干基本概念
语言的运算
描述 运算
语言L和语言M
连接(积) LM={ xy| x∈L 且 y∈M }
合并(和) 闭包 正闭包
文法G是二义性文法,如果它的某个句子有两种不 同的最左(或最右)推导;或有两棵不同的分析树。 该句子称为文法G的二义性句子。
二义性语言
语言L是二义性的语言,如果不存在能产生它的非 二义性的文法;或者能产生该语言的文法均为二义 性文法。
2024/7/8
《编译原理与技术》讲义
35
若干基本概念- 二义性文法
编译原理与技术
2020/4/11
《编译原理与技术》讲义
2
自底向上分析
分析技术的关键-句柄的识别
句柄(handle)是什么? 一般地,如果有以下最右推导序列,
S r*m A rm ,AP
则产生式A及其在右句型中的位置称为右 句型的句柄。
2020/4/11
《编译原理与技术》讲义
3
自底向上分析
e.g.17 文法G6
《编译原理与技术》讲义
9
自底向上分析
e.g.17 文法G6 1)SaABe 2)AAbc 3)Ab 4)Bd
串abbcde$的对应分析树 的建立过程。
AB A
2020/4/11
输入串 a b b c d e $
《编译原理与技术》讲义
10
自底向上分析
e.g.17 文法G6 1)SaABe 2)AAbc 3)Ab 4)Bd
28
e.g.21 表达式文法G2的LR分析表(续)
状
action
态 id + * ( ) $
7 s5
s4
8
s6
s11Biblioteka Baidu
9
r1 s7
r1 r1
10
r3 r3
r3 r3
11
r5 r5
r5 r5
goto ETF
10
2020/4/11
编译原理与技术练习题汇总
编译原理与技术练习题汇总
练习 1
1.1 为什么⾼级程序语⾔需要编译程序?
1.2 解释下列术语:
源程序,⽬标程序,翻译程序,编译程序,解释程序
1.3 简单叙述编译程序的主要⼯作过程。
1.4 编译程序的典型体系结构包括哪些构件,主要关系如何,请⽤辅助图⽰意。
1.5 编译程序的开发有哪些途径?了解你熟悉的⾼级编程语⾔编译程序的开发⽅式。
1.6 运⽤编译技术的软件开发和维护⼯具有许多类,简单叙述每⼀类的主要⽤途。
1.7 了解⼀个真实编译系统的组成和基本功能。
1.8 简单说明学习编译程序的意义和作⽤。
1.9 如果机器H上有两个编译:⼀个把语⾔A翻译成语⾔B,另⼀个把B翻译成C,那么可以把第⼀个编译的输出作为第⼆个编译的输⼊,结果在同⼀类机器上得到从A到C的编译。请⽤T形图⽰意过程和结果。
练习 2
2.1 词法分析器的主要任务是什么?
2.2 下列各种语⾔的输⼊字母表是什么?
(1) C
(2) Pascal
(3) Java
(4) C#
2.3 可以把词法分析器写成⼀个独⽴运⾏的程序,也可以把它写成⼀个⼦程序,请⽐较各⾃的优劣。
2.4 ⽤⾼级语⾔编写⼀个对C#或Java程序的预处理程序,它的作⽤是每次调⽤时都把下⼀个完整的句⼦送到扫描缓冲区,去掉注释和⽆⽤的空格、制表符、回车、换⾏。
2.5 ⽤⾼级语⾔实现图2.5所⽰的Pascal语⾔数的状态转换图。
2.6 ⽤⾼级语⾔编程实现图2.6所⽰的⼩语⾔的词法扫描器。
2.7 ⽤⾃然语⾔描述下列正规式所表⽰的语⾔:
(1) 0(0|1)*0
(2) ((ε|0)1)*)*
编译原理-课程简介
05
CATALOGUE
编ቤተ መጻሕፍቲ ባይዱ器实现技术
词法分析器实现方法
基于正则表达式的词法分析
01
利用正则表达式描述词法单元的模式,通过模式匹配进行词法
分析。
基于状态机的词法分析
02
根据词法单元的规则构建状态机,通过状态转移进行词法分析
。
手工编写的词法分析器
03
根据语言规范,手动编写代码实现词法分析器。
语法分析器实现方法
• 向量化技术的实现方法:向量化技术的实现方法包括自动向量化和手动向量化 两种。自动向量化是指编译器自动将程序中的循环结构转换为向量运算;而手 动向量化则需要程序员手动编写向量运算的代码。在实现向量化技术时,需要 注意处理器的向量长度、数据对齐等问题。
04
CATALOGUE
运行时环境支持
存储管理策略及实现
• 循环优化的概念和作用:循环优化是编译器优化中针对循环结构的一种特殊优 化技术,它可以显著提高循环程序的性能。
• 循环优化的方法:常见的循环优化方法包括循环展开、循环合并、循环交换等 。这些方法可以减少循环次数、消除循环中的冗余计算和提高循环的并行度。
• 向量化技术的概念和作用:向量化技术是一种利用现代处理器中的向量运算单 元来提高程序性能的优化技术。通过向量化技术,编译器可以将多个标量运算 转换为单个向量运算,从而显著提高程序的运算速度。
编译原理技术和工具
编译原理技术和工具
编译原理技术和工具是计算机科学中非常重要的一门课程,它主要涉及编译器的设计和实现。编译器是将高级语言编写的程序转换成机器语言的程序,它是计算机系统的核心组件之一。编译原理技术和工具主要包括以下内容:
1. 词法分析器:它负责将源程序分解成一个个单词(token),并将这些单词转换成机器可以识别的形式。
2. 语法分析器:它负责将单词流转换成语法树,并进行语法检查,确保程序符合语法规范。
3. 语义分析器:它负责对程序进行语义检查,确保程序符合语义规范。
4. 中间代码生成器:它负责将程序转换成中间代码,这样可以便于后续处理。
5. 优化器:它负责对中间代码进行优化,提高程序的执行效率。
6. 目标代码生成器:它负责将中间代码转换成机器代码,使得程序可以在计算机上运行。
在编译原理技术和工具方面,有很多常用的工具和技术,例如Flex和Bison、LLVM等。这些工具和技术可以大大提高编译器的开发效率和质量。在学习编译原理技术和工具时,我们需要掌握这些工具和技术的原理和使用方法,同时也需要了解编译器的整个编译流程和各个组件之间的关系。
- 1 -
《编译原理》教学大纲
《编译原理》教学大纲
一、课程概述
编译原理是计算机科学与技术专业的一门重要课程,也是软件工程领域的基础课程之一、本课程通过对编译器的原理和实现技术的学习,使学生掌握编译器的设计和实现方法,培养学生独立解决实际问题的能力。
二、教学目标
1.理解编译器的基本原理和工作流程;
2.掌握常见编译器的构建方法和技术;
3.能够设计和实现简单的编译器;
4.培养分析和解决实际问题的能力。
三、教学内容和教学进度
1.第一章:引论
1.1编译器的定义和分类
1.2编译器的基本工作流程
2.第二章:词法分析
2.1编译器的基本结构
2.2词法单元的定义和识别方法
2.3正则表达式和有限自动机
3.第三章:语法分析
3.1语法分析的基本概念
3.2语法规则的定义和表示方法
3.3自顶向下的语法分析方法
3.4自底向上的语法分析方法
4.第四章:语义分析
4.1语义分析的基本概念
4.2属性文法和语法制导翻译
4.3语义动作和符号表管理
5.第五章:中间代码生成
5.1中间代码的定义和表示方法
5.2基本块和控制流图
5.3三地址码的生成方法
6.第六章:优化
6.1优化的基本概念和原则
6.2常见的优化技术和方法
6.3编译器的优化策略
7.第七章:目标代码生成
7.1目标代码生成的基本原理
7.2目标代码的表示方法和存储管理
7.3基本块的划分和目标代码生成算法
8.第八章:附加主题
8.1解释器和编译器的比较
8.2面向对象语言的编译
8.3并行编译和动态编译
四、教学方法
1.理论教学与实践相结合,注重教学案例的分析和实践;
2.引导学生主动探索,注重培养学生的自主学习能力;
编译原理与技术 - 习题集(含答案)
编译原理与技术 - 习题集(含答案)
《编译原理与技术》课程习题集
西南科技大学成人、网络教育学院版权所有
习题
【说明】:本课程《编译原理与技术》(编号为03002)共有简答题,计算题1,计算题2,问答与作图题,计算题3,计算题4,计算题5等多种试题类型,其中,本习题集中有[简答题]等试题类型未进入。
一、计算题1 1. 已知NFA M
1、将NFA M确定化为DFA M;
2、求DFA M的正规式; 2. 已知正规式:
a+b(b|ab)*
1、求等价的NFA;
2、求等价的DFA; 3. 已知正规式((ε|a)b*)*
1、求等价的NFA;
2、将NFA确定化
3、若所求DFA可最小化,则求其最小化DFA;若无,说明原因。 4. 写出字母表? = {a, b}上语言L = {w | w中a的个数是偶数}的正规式,并画出
接受该语言的最简DFA。
5. 有文法 G[S] :
第 1 页共 26 页
S → aC | aA A → aC C → bC |b
1、求等价的NFA;
2、求等价的DFA;
二、计算题2 6. 将文法G[S]:
S→aA A→AS|Bc B→Bi|i
1、消除左递归;
2、证明该文法消除左递归后是LL(1)文法?
3、给出相应的LL(1)分析表。
7. 已知文法G(S):
E→aTb|iE|i T→TE|E
1、提公因子和消除左递归;
2、计算每个非终结符的FIRST和FOLLOW;
3、证明该文法是否为LL(1)文法?
8. 已知文法G(S)为:
E → E or T | T T → T and
F | F
F → not F | ( E ) | true | false 1、对文法消除左递归;
编译原理原理与技术
2018/12/26
《编译原理与技术》讲义
有限自动机识别的语言
e.g.10 下面DFA M识别的语言L(M)是什么?
0 S0 1 1 S1 0 0
1 S2
2018/12/26
《编译原理与技术》讲义
13
有限自动机识别的语言
e.g.10 L(M) = { 能被“3”整除的二进制数(串) }
1
输入串
2018/12/26
0
0 0 1 0
15
1
《编译原理与技术》讲义
比较 DFA 和 NFA(1)
DFA NFA
:S x S
没有 转换
:S x 2S
有 转换
对∈*,DFA的“识别” 对∈*的“识别”路径可 路径唯一且完全由确定 能存在多条不同的路径 对于正规式R,均有DFA Md和NFA Mn,使得L(Md) = L(Mn)=L(R),即两者识别正规语言能力相同(等价)
L(M) = L(R) ,反之亦然。 Thopmson 方法:
R=
R=∅ R=a∈
2018/12/26
S0 S0
S0 a
只引入初态S0和 终态S1,他们之 间无状态转换
S1
S1
19
《编译原理与技术》讲义
正规式与有限自动机
R= R1 | R2
编译原理书籍
编译原理书籍
编译原理是计算机科学领域的重要课题之一。它研究的是如何将高级程序语言代码转换为可执行的机器语言代码的过程。编译原理的研究对于优化程序性能、提高程序可靠性以及实现新的语言特性都具有重要意义。
在编译原理的学习过程中,一本好的教材是必不可少的辅助工具。以下是一些值得推荐的编译原理教材:
1. "编译原理与技术",作者:王生原
2. "编译原理",作者:周伯华
3. "现代编译原理",作者:Andrew W. Appel
4. "编译原理与实践",作者:龙书
5. "高级编译器设计与实现",作者:Steven Muchnick
这些教材涵盖了编译原理的基本概念、各个阶段的具体实现、相应的算法和数据结构等内容。通过系统地学习这些教材,读者可以掌握编译原理的核心知识,并且能够应用于实际的编译工作中。
除了教材之外,还可以参考相关的学术论文、技术博客和开源项目,以获取更深入的理解和实战经验。编译原理是一个广阔而有挑战性的领域,需要不断学习和实践才能掌握其中的精髓。愿你在学习编译原理的过程中能够获得丰富的知识和宝贵的经验!
编译原理概述
编译原理概述
编译原理是计算机科学中的重要概念,是指设计和构建编译器的理论和技术。编译器是一种将高级语言代码翻译成底层机器语言代码的程序,它起着将源代码翻译成目标代码的作用。编译原理的主要研究对象是编译器的构造和实现方法,以及编译过程中涉及的各种理论和技术问题。
编译原理的基本概念包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等几个方面。其中,词法分析是将源代码分解成一个个单词或记号的过程,语法分析是对单词或记号进行语法规则分析的过程,语义分析是确定代码真正含义的过程,中间代码生成是生成与源代码等价的目标代码的过程,代码优化是提高目标代码质量和性能的过程,目标代码生成是将中间代码翻译成机器代码的过程。
在编译原理中,最核心的部分是语法分析,它决定了编译器对源代码的理解和转换能力。语法分析可以分为自上而下的分析方法和自下而上的分析方法。自上而下的分析方法是从最抽象的语法规则开始逐步向下分解源代码,直到分解到最细粒度;自下而上的分析方法则是从最细粒度的语法规则开始逐步向上合成源代码,直到合成到最抽象的语法规则。
在编译原理的研究中,还涉及到一些高级主题,如编译器前端和后端的设计、编译器生成器的设计、抽象语法树和符号表的表示、代码生成技术、及时编译技术等。
总的来说,编译原理是计算机科学中非常重要的一个领域,它的研究成果直接影响着编程语言的设计和实现方式,也是软件工程师必须掌握的基础知识之一。通过学习编译原理,可以更好地理解计算机语言的工作原理,提高编程能力和代码质量,为软件开发提供更好的支持和保障。
编译原理实验课程教案
编译原理实验课程教案
一、课程概述
编译原理是计算机科学与技术专业的一门重要课程,主要介绍编译器的原理、设计和实现方法。编译原理实验课程是编译原理理论课程的实践环节,旨在通过实际操作,加深学生对编译原理相关概念和算法的理解,提高编程能力和软件开发能力。
二、课程目标
1. 理解编译器的基本原理和工作流程;
2. 学习编译器设计和实现的基本方法和技术;
3. 掌握编译器前端和后端的关键技术和算法;
4. 培养学生的问题分析和解决能力;
5. 提高学生的编程能力和软件开发能力。
三、教学内容与安排
1. 实验1:词法分析器设计与实现
- 理解词法分析的基本概念和任务;
- 学习正则表达式和有限自动机的基本原理;
- 设计并实现一个简单的词法分析器。
2. 实验2:语法分析器设计与实现
- 理解语法分析的基本概念和任务;
- 学习上下文无关文法和语法分析器的基本原理;
- 设计并实现一个简单的语法分析器。
3. 实验3:语义分析器设计与实现
- 理解语义分析的基本概念和任务;
- 学习语义动作和语义分析器的基本原理;
- 设计并实现一个简单的语义分析器。
4. 实验4:中间代码生成与优化
- 理解中间代码的基本概念和任务;
- 学习中间代码生成和优化的基本原理;
- 设计并实现一个简单的中间代码生成器和优化器。
5. 实验5:目标代码生成与优化
- 理解目标代码的基本概念和任务;
- 学习目标代码生成和优化的基本原理;
- 设计并实现一个简单的目标代码生成器和优化器。
四、实验环境与工具
为了完成编译原理实验课程,学生需要具备以下环境和工具:
1. 操作系统:Windows、Linux或Mac OS;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
程序单元的激活(调用)与终止(返回) 程序单元的执行需要:
代码段+活动记录(程序单元运行所需的额 外信息,如参数,局部数据,返回地址等)
2019/11/8
2019/11/8
《编译原理与技术》-运行环境
6
活动记录的内容
返回值(return value) 实在参数(actual parameter) 控制链(control link)
可选的访问链(optional access/static link)
机器状态(saved machine status) 局部数据(local data) 临时区(temporaries)
I ( 100 )
第二次调用sub,输出100
第二次调用后 机器状态
I ( 100 )
2019/11/8
《编译原理与技术》-运行环境
11
动态存储分配
栈式分配 - AR在过程被调用(激活)时才在栈 (stack)上分配;而在被调用过程(返回) 终止时从栈上撤销。 - 过程中(非静态)局部变量的存储绑定在 过程执行时有效;过程终止时失效。 - 支持过程递归调用。每次递归调用时,局 部变量绑定到不同的存储。
栈顶sp 临时区
长度可变的区 域放在AR低端
2019/11/8
《编译原理与技术》-运行环境
13
栈式分配下的过程调用与返回
- 过程调用:分配被调过程的AR并填入相关信息, 然后程序控制转移到被调过程入口;
-过程A 调用 过程B 的过程调用序列:
A的“调用”准备操作:1)~ 3)
1)A 计算实在参数并放入(对应栈操作-push) B的活动记录中;(亦可考虑返回值存放空间)
{ int b = 1 ; // block 1 { int a = 2 ; printf(“%d %d\n”,a,b);//block 2 } { int b = 3 ; printf(“%d %d\n”,a,b);//block 3 } printf(“%d %d\n”,a,b);
} printf(“%d %d\n”,a,b); }
2)A将可选的访问链放入(push)B的活动记录;
3)A将返回地址放入B的活动记录并跳转到过程B 的代码入口,开始B的执行;(一般通过A中的 代码指令-“call B” 来完成这一步)
4)
2019/11/8
《编译原理与技术》-运行环境
14
栈式分配下的过程调用与返回 -过程A 调用 过程B 的过程调用序列: B的入口代码:4)~ 6) 4)在B自己的AR中保存A的活动记录的基址
2019/11/8
《编译原理与技术》-运行环境
25
分程序的实现
1)按无参过程方式来实现
-控制流进入分程序时,在栈上分配局部变量空间 ,退出时撤销上述空间。e.g.6中各变量存储如下:
a0 = 0 b0 = 0 b1 = 1
a0 = 0 b0 = 0 b1 = 1 a1 = 2
a0 = 0 b0 = 0 b1 = 1 b2 = 3
《编译原理与技术》-运行环境
3
运行时内存划分
代码段 静态数据区 栈(stack)
大小可以静态确定 全局/局部静态变量 活动记录栈
堆(heap)
动态分配的数据
2019/11/8
《编译原理与技术》-运行环境
4
活动记录
活动记录-AR (Activation Record) 是一连续存储区域,用于管理与存放和程序 单元执行相关的重要信息。
2019/11/8
《编译原理与技术》-运行环境
18
e.g.2 栈式存储分配
过程g被调用时,活动记录栈的(大致)内容
2019/11/8
返回地址
old bp
a : 1000 返回地址
old bp
a : 100
返回地址
bp
old bp
a : 10 sp
main程序的AR 函数h的AR 函数g的AR
《编译原理与技术》-运行环境
主程序 : 0
嵌套深度:1
A:1
var j : integer; procedure C ;
嵌套深度:2
i: 2
begin
B;
C
B:2
end; begin
j := i;
BA 主程序
嵌套深度:3
j: 3
C;
C:3
end;
begin
B;
2019/11/8
《编译原理与技术》-运行环境
7
活动记录内容的存取
AR的基地址bp
返回值 实在参数 控制链 (old bp)
可选的访问链
机器状态 局部数据 临时区
2019/11/8
《编译原理与技术》-运行环境
8
活动记录内容的存取
返回值
地址:
实在参数
bp+d1
偏 移
控制链(old bp)
d1
可选的访问链
2019/11/8
《编译原理与技术》-运行环境
10
e.g.1 FORTRAN静态存储分配
CALL sub
SUBROUTINE sub
CALL sub END
DATA I/10 WRITE(*.*) I
第一次调用前 机器状态
I = 100
I ( 10 )
END 第一次调用sub,输出10
第一次调用后 机器状态
“最接近嵌套” 序)
vs. 现行单元活动(调用次
分程序
- 含有声明和语句;如C的{…}
- 分程序具有以下特征:
-- 可以嵌套;
-- 没有参数;
-- 控制流沿静态文本进入、流出
-- 采用“最接近嵌套”的规则
2019/11/8
《编译原理与技术》-运行环境
24
非局部变量访问
e.g.6 分程序 main() { int a = 0 ; int b =0; //local VAR of main
a0 = 0 b0 = 0 b1 = 1 a1 = 2 b2 = 3
b)a1和b2将被分配在不同 的空间。
2019/11/8
《编译原理与技术》-运行环境
27
过程嵌套定义语言中非局部名字访问
program dynamic_static_link; procedure A ; var i : integer ; procedure B ;
(即当前bp,对应操作 push bp)并且将这 个位置作为B自己AR的基址(对应操作)
mov sp,bp 即 bpsp) 5)保存可选的机器状态(寄存器) 6)为局部数据分配空间,(对应操作) sub local_size,sp,即sp sp – local_size 7)“开始”B的执行。(至此,B的AR建好)
《编译原理与技术》-运行环境
21
e.g.4. scanf的可变参数
&f &i 格式串1指针 返回地址 老bp … …
bp+8 bp
&j 格式串2指针
返回地址 老bp … …
scanf的第一次调用时AR scanf的第二次调用时AR
由于C语言采用 逆序传递参数, 格式串参数将被 放在AR中的“固 定”位置,即 bp+8。而由此参 数即可确定待输 入值的参数(变 量)的个数。从 而适应参数个数 变化的情况。
20
e.g.4. scanf的可变参数
有如下C程序: main() { int i ; float f; int j ; scanf(“%d%f”, &i, &f); //第一次调用时3个参数 scanf(“%d”, &j ); //第二次调用时 2个参数 return 0; }
2019/11/8
《编译原理与技术》-运行环境
26
分程序的实现
2)按过程为单位统一分配
-将分程序中的局部变量独立地看成过程的局部变 量。e.g.6中各变量存储如下: (两种方案)
a0 = 0
b0 = 0 b1 = 1
a1 = 2, b2 = 3
a)a1和b2将先后被分配在 同一空间,因为它们的生 存期(作用域)不重叠、 不嵌套。
d1、d2谁正谁负?
bp
机器状态
偏移d2 局部数据
临时区
地址: bp+d2
2019/11/8
《编译原理与技术》-运行环境
9
静态存储分配
- 全局变量的存储绑定、AR均在编译时确定 且在整个程序执行中保持。
- 不支持: 1)动态数据结构 2)过程递归调用
- 实现静态分配的语言: (早期)FORTRAN
AR中的内容 - 临时区域。用以保存临时计算结果
- 局部数据区。源程序中程序单元声明的局 部变量对应在此区域。
- 机器状态保存区。存有机器的寄存器,程 序指令计数器 ip(返回地址)等。
2019/11/8
《编译原理与技术》-运行环境
5
活动记录
AR中的内容 - 访问链(静态链)。当前程序单元可以访 问的(静态程序中)外围程序单元的活动记 录链。 - 控制链(动态链)。程序单元的活动记录 按它们的生成(或调用)次序串成链。 - 实在参数 - 返回值
19
e.g.3 有参函数的活动记录
参数 b 参数 a 返回地址 老bp 局部变量c 局部变量d
bp+12 bp+8
bp bp-4 bp-8
.file "ar.c"
void func( int a , int b )
.text
{
.globl func
int c , d;
.type func,@function
2019/11/8
《编译原理与技术wenku.baidu.com-运行环境
15
栈式分配下的过程调用与返回
- 过程返回:回收分配的被调过程的AR,并将程 序控制转移回调用过程继续执行;
-过程A 调用 过程B 的过程返回序列:
B的出口代码:1)~ 2)
1)B回收局部数据空间;恢复原先保存的机器状态 2)B恢复A的AR基址;取出返回地址将程序控制交 回到A。对应操作:
编译原理与技术
运行环境
2019/11/8
《编译原理与技术》-运行环境
1
运行环境
存储组织与分配
程序单元、运行时内存划分与活动记录 静态/动态存储分配 动态栈式的过程调用/返回 非局部名字的访问
参数传递
参数传递的方式及其实现
2019/11/8
《编译原理与技术》-运行环境
2
存储组织与分配
至此,B的AR区域全部回收(撤销)了。
2019/11/8
《编译原理与技术》-运行环境
17
e.g.2 栈式存储分配
有C程序如下: void g() { int a ; a = 10 ; } void h() { int a ; a = 100; g(); } main() { int a = 1000; h(); }
a0 = 0 b0 = 0 b1 = 1
a0 = 0 b0 = 0
a)进入block 1, b)进入block 2, c)退出block 2, d)退出block 3, e)退出block 1,
未进入block 2 未进入block 3 进入block 3
进入block 1
进入main
2019/11/8
c = a;
func:
d = b;
pushl %ebp
}
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
movl 12(%ebp), %eax
movl %eax, -8(%ebp)
leave
ret
2019/11/8
《编译原理与技术》-运行环境
mov bp,sp spbp
pop bp
//恢复调用者A的bp
ret
// B执行结束并返回
注:X86-Linux中的leave 和ret组合亦能达到目的。
至此,B的AR中除了参数/返回值区域,其余区域全部 回收(撤销)了。
2019/11/8
《编译原理与技术》-运行环境
16
栈式分配下的过程调用与返回 -过程A 调用 过程B 的过程返回序列: A的“调用”善后代码:3)~ 4) 3)A取回返回值以及引用型参数(有的话) 4)A调整栈顶sp(主要根据参数个数以及可 能有的访问链和可能有的返回值)。对应操 作: add para_size, sp 即spsp + para_size
2019/11/8
《编译原理与技术》-运行环境
22
e.g.5 悬空引用
有C程序如下: main() {
int * p = dangle(); … }
int * dangle() {
int i; return &i; }
2019/11/8
《编译原理与技术》-运行环境
23
非局部变量访问
静态作用域规则 vs. 动态作用域规则
2019/11/8
《编译原理与技术》-运行环境
12
动态存储分配
栈式分配下的AR内容布局
高地址
返回值 实在参数
可选的访问链
参数/返回值区域放在AR 高端-靠近调用者过程的 活动记录,既便于双方存 取,又适应参数可变情况
返回地址
bp
调用者 bp
长度固定的区 域放在AR中间
可选机器状态
低地址
局部数据