编译原理实验整体(3)目标代码生成

合集下载

编译原理目标代码生成

编译原理目标代码生成

中间代码生成
探讨中间代码的概念、作用和生成方法,包括抽象语法 树、三地址代码等中间表示形式。
代码优化
介绍代码优化的原理和常用技术,如常量折叠、复制传 播、死代码删除等,以提高目标代码的质量。
目标代码生成
详细讲解目标代码生成的过程和方法,包括指令选择、 寄存器分配、汇编语言输出等关键步骤,以及针对不同 目标平台的优化策略。
语义分析
介绍了语义分析的基本任务,如类型 检查、控制流分析、数据流分析等。
中间代码生成
阐述了中间代码的概念、作用及生 成方法,包括抽象语法树、三地址 代码等。
目标代码生成
详细讲解了目标代码生成的过程, 包括指令选择、寄存器分配、优化 等。
对未来编译技术的展望
智能化编译技术
随着人工智能技术的发展,未来编译器可能具备更强的自 主学习能力,能够自动优化代码性能、提高编译效率。
01
指令选择算法
根据目标计算机的指令集和程序语义, 选择最合适的指令来实现程序功能。
02
03
代码优化算法
通过对生成的机器相关代码进行各种 优化(如常量折叠、循环展开等), 提高其执行效率和资源利用率。
06
代码生成器的设计与实现
代码生成器的结构
中间代码生成器
将源程序转换为中间代码形式,便于后续优化和代码生成。
2
编译过程包括词法分析、语法分析、语义分析、 中间代码生成、代码优化和目标代码生成等阶段。
3
编译原理不仅关注如何生成高效的目标代码,还 关注如何提高编译器的可维护性、可移植性和可 扩展性。
目标代码生成的意义
提高程序执行效率
目标代码是计算机直接执行的指令,其执行效率远高于高级语言程序。通过优化目标代码 ,可以提高程序的执行速度。

《编译原理教程》第七章目标代码生成

《编译原理教程》第七章目标代码生成

中间代码优化的重要性
提高目标代码质量
通过消除冗余和无用代码、减少计算量、改进数据结构等方式,中间代码优化可以显著提高目标代码的质量和执行效 率。
降低硬件资源消耗
通过优化循环、减少内存访问等手段,中间代码优化可以减少硬件资源的消耗,如CPU、内存和存储器等,从而降低 系统成本和能耗。
提升软件可维护性和可靠性
案例二:控制流程的目标代码生成
总结词
通过生成条件语句和循环语句的目标代码,展示了控制流程的目标代码生成方法。
详细描述
对于条件语句,如"if a>b then c else d",生成的条件分支目标代码会根据条件表达式的值选择执行相应的语句。 对于循环语句,如"for i=0 to n do ... next",生成的目标代码会包含循环变量的初始化、循环条件检查和循环体 的执行。
案例三:复杂数据结构的目标代码生成
总结词
通过生成复杂数据结构(如数组和结构体)的目标代码,展示了目标代码生成在处理复杂数据结构时 的应用。
详细描述
对于数组,生成的目标代码会包含数组的声明、初始化和访问。对于结构体,生成的目标代码会包含 结构的声明、实例化和成员访问。例如,对于一个包含整型变量a和浮点型变量b的结构体,生成的目 标代码会包含结构体的声明、实例化以及访问结构体成员的指令。
03
提高执行效率
目标代码通常比源代码更 接近机器语言,因此执行 效率更高。
兼容性
目标代码可以在不同的计 算机和操作系统上运行, 提高了程序的兼容性。
安全性
目标代码可以隐藏源代码 中的敏感信息,提高程序 的安全性。
目标代码生成的基本步骤
语法分析
根据语法规则将词素组合成抽 象语法树(AST)。

编译原理实验:目标代码的生成

编译原理实验:目标代码的生成

5. 目标代码生成本章实验为实验四,是最后一次实验,其任务是在词法分析、语法分析、语义分析和中间代码生成程序的基础上,将C 源代码翻译为MIPS32指令序列(可以包含伪指令),并在SPIM Simulator上运行。

当你完成实验四之后,你就拥有了一个自己独立编写、可以实际运行的编译器。

选择MIPS作为目标体系结构是因为它属于RISC范畴,与x86等体系结构相比形式简单便于我们处理。

如果你对于MIPS体系结构或汇编语言不熟悉并不要紧,我们会提供详细的参考资料。

需要注意的是,由于本次实验的代码会与之前实验中你已经写好的代码进行对接,因此保持一个良好的代码风格、系统地设计代码结构和各模块之间的接口对于整个实验来讲相当重要。

5.1 实验内容5.1.1 实验要求为了完成实验四,我们建议你首先下载并安装SPIM Simulator用于对生成的目标代码进行检查和调试,SPIM Simulator的官方下载地址为:/~larus/spim.html。

这是由原Wisconsin-Madison的Jame Larus教授(现在在微软)领导编写的一个功能强大的MIPS32汇编语言的汇编器和模拟器,其最新的图形界面版本QtSPIM由于使用了Qt组件因而可以在各大操作系统平台如Windows、Linux、Mac等上运行,推荐安装。

我们会在后面介绍有关SPIM Simulator的使用方法。

你需要做的就是将实验三中得到的中间代码经过与具体体系结构相关的指令选择、寄存器选择以及栈管理之后,转换为MIPS32汇编代码。

我们要求你的程序能输出正确的汇编代码。

“正确”是指该汇编代码在SPIM Simulator(命令行或Qt版本均可)上运行结果正确。

因此,以下几个方面不属于检查范围:1)寄存器的使用与指派可以不必遵循MIPS32的约定。

只要不影响在SPIM Simulator中的正常运行,你可以随意分配MIPS体系结构中的32个通用寄存器,而不必在意哪些寄存器应该存放参数、哪些存放返回值、哪些由调用者负责保存、哪些由被调用者负责保存,等等。

编译原理中的目标代码生成与优化

编译原理中的目标代码生成与优化

编译原理中的目标代码生成与优化编译原理是计算机科学中的一门重要课程,它研究的是将高级程序语言转化为机器语言的过程。

目标代码生成与优化是编译过程中的两个关键环节,本文将就这两个方面展开讨论。

一、目标代码生成目标代码生成是编译过程中的最后一步,它的任务是将中间代码转化为能够在目标机器上执行的机器代码。

目标代码生成的质量直接影响程序的执行效率和占用的存储空间。

1. 寄存器分配在进行目标代码生成之前,我们需要进行寄存器分配。

寄存器分配的目的是将中间代码中的临时变量分配到机器寄存器中,减少内存读写操作,提高程序的运行速度。

常用的寄存器分配算法有线性扫描算法和图着色法。

2. 目标代码生成技术目标代码生成的技术有很多,下面列举几种常见的技术:(1) 直接生成代码:直接将中间代码翻译为目标机器的指令序列。

这种方法简单直接,但生成的目标代码质量一般较低。

(2) 间接生成代码:先将中间代码翻译为一个中间形式,再将中间形式转化为目标机器的指令序列。

这种方法可以进行一些优化,生成的目标代码质量较高。

(3) 使用代码模板:事先定义一些目标机器的指令模板,并根据中间代码的特征选择合适的指令模板来生成目标代码。

这种方法可以充分利用目标机器的特性,生成的目标代码效率较高。

二、目标代码优化目标代码优化是指对生成的目标代码进行一系列的优化,以提高程序的运行效率和减少代码的空间占用。

1. 基本块优化基本块是由顺序执行的指令组成的,没有前驱指令和后继指令的指令序列。

基本块优化的目的是对基本块中的指令进行优化,以减少执行时间和空间开销。

常见的基本块优化技术有死代码删除、常量传播等。

2. 寄存器优化寄存器是计算机中的一块高速存储器,能够提供快速的数据访问速度。

寄存器优化的目的是将变量尽可能地存放在寄存器中,以减少内存读写操作,提高程序的执行效率。

常用的寄存器优化技术有寄存器分配、寄存器重命名等。

3. 循环优化循环是程序中的重要结构之一,对循环进行优化可以显著提高程序的执行效率。

实验报告编译实验

实验报告编译实验

一、实验目的1. 理解编译原理的基本概念和过程。

2. 掌握编译器的基本组成和编译流程。

3. 学会使用编译器对源代码进行编译,并分析编译结果。

二、实验环境1. 操作系统:Windows 102. 编译器:GCC (GNU Compiler Collection)3. 开发工具:Visual Studio Code三、实验内容1. 编译器的基本组成和编译流程2. 编译器的使用3. 编译结果分析四、实验步骤1. 编译器的基本组成和编译流程(1)词法分析:将源代码分解成一个个的单词,如标识符、关键字、运算符等。

(2)语法分析:将单词序列转换成语法树,验证源代码是否符合语法规则。

(3)语义分析:检查语法树,确保源代码在语义上是正确的。

(4)中间代码生成:将语法树转换成中间代码,如三地址代码。

(5)代码优化:对中间代码进行优化,提高程序运行效率。

(6)目标代码生成:将优化后的中间代码转换成目标代码,如汇编代码。

(7)代码生成:将目标代码转换成可执行文件。

2. 编译器的使用(1)编写源代码:使用Visual Studio Code编写C语言源代码。

(2)编译源代码:在命令行中输入gcc -o 程序名源文件名.c,编译源代码。

(3)运行程序:在命令行中输入程序名,运行编译后的程序。

3. 编译结果分析(1)词法分析:编译器将源代码中的单词进行分解,如以下代码:```cint main() {int a = 1;return a;}```编译器将分解为以下单词:- int- main- (- )- {- int- a- =- 1- ;- return- a- ;- }- }(2)语法分析:编译器将单词序列转换成语法树,验证源代码是否符合语法规则。

(3)语义分析:编译器检查语法树,确保源代码在语义上是正确的。

(4)中间代码生成:编译器将语法树转换成中间代码,如以下三地址代码:```t1 = 1a = t1t2 = areturn t2```(5)代码优化:编译器对中间代码进行优化,如以下优化后的三地址代码:```a = 1return a```(6)目标代码生成:编译器将优化后的中间代码转换成汇编代码。

编译原理 目标代码生成 流程代码解析

编译原理 目标代码生成 流程代码解析

N
将栈中元素存到数 组,出栈
目标代码生成流程图:
6
开始 扫描逆波兰式
结束
Y
逆波兰式扫
描完
N
滤掉逆波兰式中 逗号
当前字符串为是否 不为运算分量,逗号
Y
当前字符存入数 组
Y N
当前字符串为是 否不为运算分量
N
当前字符串是 否为运算分量
N是否为寄存器, 用@等字符代表寄存器
MOV
传送字或字节.
算术运算指令
ADD
加法
算术运算指令
SUB
减法
算术运算指令
MUL
无符号乘法
算术运算指令
DIV
无符号除法
……
……
……
5. 实验代码
/******************************************************************************/ #include<iostream> #include<string> #include<stack> using namespace std; string temp1(8,0),temp2(8,0),value1; /******************************************************************************/ bool Ispair(string expre) { bool flag=true; stack<char> s; for(int i=0;i<expre.length();i++) { if(expre[i]=='(') s.push(expre[i]); if(expre[i]==')') { if(s.empty()) { flag=false; return flag; }

目标代码生成器

目标代码生成器
如果其现行值在寄存器中,则把寄存器取作 B’和 C’ 3. 如果 B’≠R,则生成目标代码:
LD R, B’
op R, C’ 否则生成目标代码 op R, C’
如果 B’或 C’为 R,则删除 AVALUE[B]或 AVALUE[C]中的 R。 4. 令 AVALUE[A]={R}, RVALUE[R]={A}。 5. 若 B 或 C 的现行值在基本块中不再被引用,也不是基本块出口之后的活 跃变量,且其现行值在某寄存器 Rk 中,则删除 RVALUE[Rk]中的 B 或 C 以及 AVALUE[B]或 AVALUE[C] 中的 Rk ,使得该寄存器不再为 B 或 C 占用。
寄存器分配:GETREG(i: A:=B op C) 返回一个用来存放 A 的值的寄存器 (1) 如果 B 的现行值在某个寄存器 Ri 中,RVALUE[Ri]中只包含 B,此外, 或者 B 与 A 是同一个标识符,或者 B 的现行值在执行四元式 A:=B op C 之后不 会再引用,则选取 Ri 为所需要的寄存器 R,并转 4; (2 ) 如果有尚未分配的寄存器,则从中选取一个 Ri 为所需要的寄存器 R, 并转 4; (3 )从已分配的寄存器中选取一个 Ri 为所需要的寄存器 R。最好使得 Ri 满足一下条件:
分配操作寄存器
R:GETREG(i:A:=B OP C)
′ 取B,C现行值存放的位置B′,C
B′:=AVALUE[B]
C′:=AVALUE[C]
yes
no
B′=R?
生成目标代码
生成目标代码
Op R,C′
LD R,B′
图 1.1
设计流程图
OP R,C′
程序代码:
#include<iostream> #include<stack>

编译原理 目标代码生成

编译原理 目标代码生成

11.1 代码生成器的设计中的问题
若不考虑目标程序的效率,指令的选择是直 截了当的。
三地址语句x := y + z(x,y和z都是静态分配) MOV y, R0 /* 把y装入寄存器R0 */ ADD z, R0 /* z加到R0上 */ MOV R0, x /* 把R0存入x中 */
11.1 代码生成器的设计中的问题
11.1 代码生成器的设计中的问题
11.1.4 计算次序的选择 某种计算次序可能会比其它次序需要较少的 寄存器来保存中间结果
11.2 目 标 机 器
11.2.1 目标机器的指令系统 选择可作为几种微机代表的寄存器机器 四字节组成一个字,有n个通用寄存器R0,R1,
…,Rn-1。 二地址指令 op 源,目的
• 每个入口语句到下一个入口语句之前的语 句序列构成一个基本块
11.3 基本块和流图
(1) prod := 0
(2) i := 1
(3) t1 := 4* i (4) t2:= a[t1] (5 ) t3 := 4* i (6 ) t4 := b[t3] (7 ) t5 := t2 * t4 (8 ) t6 := prod + t5 (9 ) prod := t6 (10) t7 := i +1 (11) i := t7 (12 ) if i <= 20 goto (3)
• 对每个基本块从最后一个语句反向扫描到 第一个语句,可以得到下次引用信息
i: x := y op z
...
--没有对x的赋值
j: … := x …
...
--没有对x的
赋值
k: … := … x
• 利 用 下 次 引 用 信 息 , 可 以 压 缩 临 时 变 量 需

编译原理之代码生成

编译原理之代码生成

03
04
05
1. 语法分析:根据语言 2. 语义分析:对抽象语
的语法规则,将源程序 法树进行语义检查和处
解析成抽象语法树
理,包括类型检查、符
(Abstract Syntax Tree,号表管理等。
AST)。
3. 中间代码生成:根据 抽象语法树和语义分析 结果,生成中间代码。 常见的中间代码形式有 三地址码、静态单赋值 形式(Static Single Assignment,SSA)等。
运行时系统自动管理程序中的内存资源, 通过垃圾回收机制回收不再使用的内存空 间,防止内存泄漏和野指针等问题。
运行时系统对程序性能的影响和优化
性能影响
运行时系统的设计和实现会直接影响程序的性能。例如,垃圾回收算法的选择和实现会 影响内存的回收效率和程序的暂停时间。线程调度策略的选择也会影响程序的并发性能
编译原理是计算机科学的重要分支,对于理解计算机如何执行程序以及如何提高程 序执行效率具有重要意义。
代码生成在编译过程中的作用
代码生成是编译过程的最后阶段, 负责将中间代码或优化后的代码 转换为目标机器上的可执行代码。
代码生成器需要了解目标机器的 指令集、寄存器分配、内存管理 等相关知识,以生成高效且正确
中间代码在编译器中的 作用主要有以下几点
使得编译过程分为相对 独立的前端和后端,降 低了编译器的复杂性。
提供了统一的中间表示, 便于实现不同语言之间 有利于进行各种优化操 的互操作性。 作。
ห้องสมุดไป่ตู้
中间代码生成的算法和步骤
01
02
中间代码生成的主要算 法包括语法分析、语义 分析和中间代码生成三 个步骤。
具体步骤如下
代码生成器的测试和评估方法

目标代码生成

目标代码生成
第9章 目标代码生成
编译程序最后一个阶段是目标代码生 成。它通常在语义分析后或者优化后的中 间代码上进行,并将中间代码转化为等价 的目标代码。
本章主要介绍
简单代码生成器的设计和构造方法
9.1 概述
我们知道,编译程序的最终目的是 将源程序翻译成等价的目标程序,为了 达到此目的,编译程序除了对源程序进 行词法分析、语法分析和语义分析外, 还必需将语义分析后或者优化后的中间 代码转换为等价的目标代码。
9.3
简单代码生成器
当翻译一个四元式如A=B op C时, 我们需要知道在基本块中还有哪些四元 式要对变量A、B、C进行引用。 2. 建立每个变量的待用信息和活跃信息 (1)待用信息
9.3

简单代码生成器
A在(i)定值 A在(j)引用
(i) A=T1 (j) T2 =A OP X
(j)为四元式(i)变量A的待用信息
9.3
简单代码生成器
(2) 活跃变量
基本块中所有的非临时变量均看 作基本块出口之后的活跃变量,临时 变量根据其在基本块出口之后是否被 引用来确定它是否为活跃变量。
9.3
简单代码生成器
(3) 计算变量待用信息和活跃信息 的算法:
输入:基本块及其入口语句号和 出口语句号 输出:附加待用信息和活跃信息 的基本块
依次把四元式变换成目标代码, 并在一个基本块内考虑如何充分利用 寄存器。 在设计代码生成器时,为考虑充分 利用寄存器,我们须要考虑下面两点:
9.3
简单代码生成器
1. 给出寄存器的分配原则
(1)把基本块内还要使用的变量的值 尽可能地保存在寄存器中; (2)在基本块内,把不再使用的变量 所占用的寄存器及时释放掉; (3)当到基本块出口时,将变量的值 存放在内存中。

深入学习:掌握编译原理与目标代码生成

深入学习:掌握编译原理与目标代码生成

深入学习:掌握编译原理与目标代码生成编译原理与目标代码生成是计算机科学与软件工程领域非常重要的一部分。

在这个领域中,我们研究的是将程序代码转换为可执行代码的过程,这涉及到了词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等一系列的技术和算法。

编译器是实现编译过程的工具,它将高级语言源代码转换为机器可执行的目标代码。

而编译过程中的关键环节即为目标代码生成,它是将中间代码转换为特定硬件平台上可执行的机器代码的过程。

编译原理的研究从上世纪50年代开始,经历了多个阶段的发展。

早期的编译器通过逐行读取源代码,然后将其转换为汇编语言或机器码。

随着计算机硬件的发展和编程语言的演化,编译器的设计和实现也发生了重大变化。

编译原理的核心概念之一是语法分析,它将源代码转换为抽象语法树(AST)。

语法分析器通过识别词法单元(如关键字、标识符、操作符等)来构建AST,并使用上下文无关文法来定义语法结构。

常见的语法分析算法有递归下降分析和LR分析。

语义分析是编译过程中的另一个重要环节,它确保程序在语义上是正确的。

语义分析器会检查源代码中的类型错误、作用域错误、类型转换错误等,并为后续的代码生成阶段提供必要的信息和约束条件。

中间代码生成是编译器的一个重要步骤,它将AST转换为一种中间表示形式,例如三地址码或者虚拟机指令。

中间代码是对源代码的一种抽象表示,它简化了后续代码生成和优化的过程,并为优化算法提供了更好的机会。

代码优化是编译过程中的重要环节,它旨在提高目标代码的性能和效率。

代码优化器使用各种技术和算法,例如常量折叠、循环优化、指令调度等,来改进目标代码的执行效率。

最后一个环节是目标代码生成,它将中间代码转化为特定硬件平台的机器代码。

目标代码生成器需要考虑到硬件平台的特点和限制,并根据目标机器的指令集架构来生成高效的机器代码。

目标代码生成是编译器的最终阶段,它决定了程序的最终执行效果。

一个好的目标代码生成器应该可以充分利用硬件资源,减少指令的数目和执行时间,从而提升程序的性能。

编译原理教程第九章目标代码生成

编译原理教程第九章目标代码生成

9.3.2 代码生成算法
假设基本块中每个中间代码形式为 A=B op C。
对每条中间代码 i:A=B op C依次执行如下步骤:
(1)调用函数GETREG(i:A=B op C); (2)利用地址描述数组AVALUE[B]和AVALUE[C]确定变量B和C的现
行值存放位置B’和C’; (3)如果B’R,则生成目标代码: LD R,B’ op R,C’ ;否则
reg的变量按需要回存到主存单元,固定分 配了reg的变量不须回存到主存单元。
a:=b+c
acde f:c=dae-fd B2
LD R0,d B0
LD R1,b
bcdf
B1
d:=adcd-bef e:=a+f
acdf
b:=d+f e:=a-c B3
cdef
b:=d+c
B4
bcdef
ST R0,d B5 ST R1,b
bcdf
B1
acde
a:=b+c d:=d-b e:=a+f acdef
acdf
f:=a-d B2 cdef
b:=d+f e:=a-c B3
cdefb:=ຫໍສະໝຸດ +cB4bcdef
bdef
分配好寄存器后,就可以生成目标代码。
与简单代码生成器不同之处在于: (1)固定分配了寄存器的变量用相应reg表示; (2)循环前置结点中存值到寄存器; (3)循环出口结点中存值到主存单元; (4)循环中每个基本块的出口,未固定分配
bdef
ST R0,d B6 ST R1,b
5 DAG的目标代码
对基本块中的中间代码序列,按怎样的次 序来生成目标代码?

编译原理中实验报告

编译原理中实验报告

实验名称:编译原理实验实验时间:2023年X月X日实验地点:实验室实验指导老师:XXX一、实验目的1. 理解编译原理的基本概念和流程。

2. 掌握词法分析和语法分析的基本方法。

3. 学习编译器生成中间代码和目标代码的过程。

4. 培养编程能力和问题解决能力。

二、实验内容本次实验主要包括以下内容:1. 词法分析:编写一个简单的词法分析器,将源代码输入转换为抽象语法树(AST)。

2. 语法分析:实现一个简单的递归下降解析器,对词法分析器输出的AST进行语法分析。

3. 中间代码生成:根据AST生成三地址代码(Three-Address Code)。

4. 代码优化:对生成的三地址代码进行优化。

5. 目标代码生成:将优化后的三地址代码转换为机器代码。

三、实验步骤1. 设计词法分析器首先,我们需要设计一个能够识别源代码中各种单词的词法分析器。

在本实验中,我们定义了以下几种单词:- 关键字:如if、else、while、int、float等。

- 标识符:由字母、数字和下划线组成,不能以数字开头。

- 常量:包括整型常量和浮点型常量。

- 运算符:如+、-、、/、==、<=等。

- 分隔符:如(、)、;、,等。

根据以上定义,我们可以编写一个词法分析器,它将输入的源代码字符串逐个字符地读取,并根据定义的规则识别出相应的单词。

2. 语法分析词法分析器生成的AST是一个树形结构,其中每个节点代表源代码中的一个单词或符号。

为了进一步分析AST的结构,我们需要实现一个递归下降解析器,它能够根据语法规则对AST进行解析。

在本实验中,我们以一个简单的算术表达式为例,实现了一个递归下降解析器。

解析器从AST的根节点开始,按照语法规则递归地解析每个子节点,直到整个表达式被解析完毕。

3. 中间代码生成在完成语法分析后,我们需要将AST转换为中间代码。

在本实验中,我们选择了三地址代码作为中间代码的形式。

三地址代码是一种表示赋值、条件判断和循环等操作的方式,它使用三个操作数和两个操作符来表示一个操作。

编译原理第10章-目标代码生成

编译原理第10章-目标代码生成

(MULTI,t2,Y,t3) LD R,t2; MUlT R,Y; ST t3,R
(MULTI,t3,t1,t4) LD R,t3; MUlT R,t1;ST t4,R;
(ASSIG,t4,-,Z) LD R, t4; ST Z,R
输入/输出语句的翻译
输入语句四元式形如:(READ, A,-,-) 汇编指令:IN R; ST A , R
几个常见指令的含义 :
Load Source R
从Source 读出送入R
Op Source R Source op R结果 送入R
Store Target R R的内容送入Target.
临时变量
特点: 寿命短; 一次定义一次使用 存储空间分配:尽可能采用共享办法
随用随分配的动态分配:
调用一个过程时,分配一个新的AR空间(不包括临 时变量部分),每当要保存一个临时变量时,动态 分配到栈区的可用单元中
循环语句的翻译
(WHILE,_,_,_)不产生目标代码,只用来标记 while语句的入口地址,将地址A入栈S;
(DO , t ,_ ,_)产生的目标代码为: LD R , t JUMP0 R , _
将“JUMP0 R , _” 入栈Q;
(ENDWHILE, _, _, _)产生的目标代码: JMP A
变量是否在寄存器中: 变量的现行值是否在内存中:
变量的值在其后是否还使用: 变量的下次引用距离:
状态描述形式(DL, SNS)
DL: 如果从下一位置开始,到变量A重新被赋值或基本 块结束,没有A的当前值的引用,则定义当前该变量的 DL为D;否则定义为L。表示此后变量的状态。 SNS: 如果A的值在寄存器但不在内存,而且当该寄存 器被剥夺时需要保存变量的值,则当前该变量的SNS的 值为S(Store),否则取NS。

目标代码生成

目标代码生成
R R0 VAR MEM
R1 …
R7
15
寄存器分配算法
• 一般在生成四元式A:=B OP C的代码中,通常把左操作 数B取到寄存器 R 中,再和C 操作( C可在内存中,也可 在寄存中),R中的结果就是A的值,或者说A占用了R. • 寄存器的分配可以用RGEREG(QUAD,R)实现,QUAD是 待分配寄存器的四元式: i: A:=B OP C , (OP,B,C,A) ; R是分配的寄存器。 (算法需查看附在四元式i上的活跃与引用信息及上表中 的结构)
Jrop P’;
7
§9.3 代码生成程序的雏形
• 为每个基本块的生成高质量代码:
– 总的指令条数要少; – 尽可能利用寄存器,少产生访问内存的指令,为 此需要充分合理的利用寄存器:
• 尽可能把后面还要引用的变量仍保存在寄存器中; • 应把不再使用的变量所占用的寄存器及时释放掉; • 为此需引入两个概念:基本块内变量的引用信息和 活跃信息。
end end;
13
四元式的附加信息
序 四元式 号 1 (-, A, B, T) 2 (+ , A, B, A) 3 (-, A, C, U) 4 (+, C, D, V) 5 (+, T, B, V) 6 (+, V, U, W) 结果 (5,Y) (3,Y) (6,Y) 左变 量 (2,Y) 右变 量 (2,Y)
符号表的变化情况
A (N, Y)→(3, Y)→(N, N)→(2, Y)→(1,Y)
B (N, Y)→(5, Y)→(2, Y)→ (1, Y) T (N, N)→(5, Y)→(N, N) C (N, Y)→(4, Y)→(3, Y) U (N, Y)→(6, Y)→(N, N)

编译学原理实验报告

编译学原理实验报告

一、实验目的1. 理解编译原理的基本概念和编译过程。

2. 掌握编译器各个阶段的功能和实现方法。

3. 通过实际操作,加深对编译原理的理解和应用。

二、实验环境1. 操作系统:Windows 102. 编译器:C++编译器3. 开发环境:Visual Studio三、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成四、实验步骤1. 词法分析(1)设计词法分析器:根据实验要求,设计一个词法分析器,能够将源代码中的字符序列转换成一个个词法符号。

(2)实现词法分析器:使用C++编写词法分析器代码,实现字符序列到词法符号的转换。

(3)测试词法分析器:编写测试用例,验证词法分析器的正确性。

2. 语法分析(1)设计语法分析器:根据实验要求,设计一个语法分析器,能够识别源代码中的语法结构。

(2)实现语法分析器:使用C++编写语法分析器代码,实现语法结构的识别。

(3)测试语法分析器:编写测试用例,验证语法分析器的正确性。

3. 语义分析(1)设计语义分析器:根据实验要求,设计一个语义分析器,能够对源代码中的语义进行验证。

(2)实现语义分析器:使用C++编写语义分析器代码,实现语义验证。

(3)测试语义分析器:编写测试用例,验证语义分析器的正确性。

4. 中间代码生成(1)设计中间代码生成器:根据实验要求,设计一个中间代码生成器,能够将源代码转换成中间代码。

(2)实现中间代码生成器:使用C++编写中间代码生成器代码,实现源代码到中间代码的转换。

(3)测试中间代码生成器:编写测试用例,验证中间代码生成器的正确性。

5. 代码优化(1)设计代码优化器:根据实验要求,设计一个代码优化器,能够对中间代码进行优化。

(2)实现代码优化器:使用C++编写代码优化器代码,实现中间代码的优化。

(3)测试代码优化器:编写测试用例,验证代码优化器的正确性。

6. 目标代码生成(1)设计目标代码生成器:根据实验要求,设计一个目标代码生成器,能够将优化后的中间代码转换成目标代码。

编译原理 第十一章 目标代码生成

编译原理 第十一章 目标代码生成

在选择指令时应注意以下几方面内容: 指令集的一致性和完整性 指令速度和机器用语 每种类型中间代码的代码框架 生成的代码的质量——取决于代码的速度和大小
充分利用计算机的寄存器对于生成好的代码是非常重要的。
寄存器的使用可分为两个子问题:
(1) 在寄存器分配期间,为程序的某 一点选择驻留在寄存器中的一组变量
所有地址均已定位,通常存放 需在要固执定行的时存,储进区行中连接,转换 为可执行的机器语言代码。
编译后可立即执行。节省时间 需需要要连汇接编装程配序程汇序编的,配产合生,可提执 供行但了的缺较机乏多器灵的语活灵言性活代,性码只用在程序不 现生不而长在成需只时大这按需多种二生数形进成实式制相的用形应代的式的码编生符。译成号程代化序码指都,令, 故最易生成。
(Ri)
(Ri) op (Rj )
(Ri)
(Ri) op ((Rj)+c) (Ri)
(Ri) op ((M)) (Ri)
(Ri) op ((Rj )) (Ri)
(Ri) op (((Rj)Fra bibliotekc)) (Ri)
指令
意义
指令
意义
LD Ri , B 取数指令(B)Ri J < X 如CT为0,转X
ST Ri , B 存数指令Ri (B) J ≤ X 如CT为0或1,转X
3.示例
1 T:= A-BB
序号图例:左值 左操作数
1
(3,y)
(2,y)
2 ( (x3,y), x ()^,^)
3
(4,y)
(^,^)
4 待(用^,信y息) 活跃(^信,^息)
右操作数
(^,^) (^,^) (4,y) (^,^)
2 U:= AA-CC 3 V:= T+U 4 W:=VV+UU

2021-2022学年编译原理之目标代码生成(3)

2021-2022学年编译原理之目标代码生成(3)
Ⅲ.【强迫释放】…… 除Ⅰ,Ⅱ情况外! ※剥夺一 Ri( 剥夺条件: 不活跃/应用点远! )
① 若 D(y)且 DRDL.M 则 { CODE( ST Ri,D ); RDL.M+=D;}
② R`:=LOCR(Ri); B`:=LOCR(B); C`:=LOCR(C); ③ RDL.Ri:=0; RETURN(R`,B`,C`);
※ x(n)不活跃;x(y)活跃;x(q) q是最近应用点(活跃);
3. 寻址函数 LOCR(x)设置,用以确认X现行值地址!
注 ※ 若 LOCR(x)= Ri --- x 值在寄存器 Ri 中! ⑴ LOCR(x)– 取操作数x地址,寄存器优先被确认! ⑵ 应用时:R`、B`和 C` 分别代表: 寄存器、变量B、和变量C的现行值地址参与运算!
13 ST R0,a
释放寄存器
习题:
【习题9.7】简要叙述在单寄存器下: ⑴ 表达式的目标代码生成算法; ⑵ 赋值语句目标代码生成算法;
【习题9.8】简要叙述目标代码生成中的寄存器分配算法; 【习题9.9】已知下列语句:
x=(a+b)/(c-d)+(a+b); ⑴ 写出优化的四元式序列; ⑵ 写出变量活跃信息(活跃)生成过程; ⑶ 描述两个寄存器(R0,R1)下的目标代码生成过程。
---- GETR(q,R`,B`,C`) 寄存器
• 支持: ⑴ 设置描述表 RDL[R1,R2,…,Rn;M], 优先被 •登录寄存器Ri,变量X的现行值状态! 确认!
算法 ⑵ 设置寻址函数 LOCR(X),确认X现行值地址!
※ 设 当前扫描的四元式为 q:( B C A )
Ⅰ. 【主动释放】
⒈ 若有Ri,使 RDL.Ri=B ;则
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理目标代码生成实验报告
班级:11203105
学号:1120310528
姓名:陈向军
一、实验目的:
通过上机实习,将前面生成的中间代码转化成汇编代码二、实验要求:
将前面生成的中间代码转化成汇编代码
三、算法思想:
与语法制导翻译相结合,将生成的中间代码转化成汇编代码
四、语法制导翻译
S' -> S ;
S -> void main ( ) { decls stmts } ;
S -> fun S ;
fun -> fun fun ;
fun -> funtype function id ( fundecls ) { decls stmts } ;
fundecls -> fundecls , fundecl ;
fundecls -> fundecl ;
fundecl -> type id ;
decls -> decls decl ;
decls -> decl ;
decl -> type ids @ ;
type -> float ;
type -> int ;
funtype -> float ;
funtype -> int ;
ids -> ids , N6 id ;
ids -> id ;
ids -> id [ num ] = { nums } ;
nums -> nums , num ;
nums -> num ;
nums -> xiao ;
stmts -> stmts stmt ;
stmts -> stmt ;
stmt -> return expr @ ;
stmt -> asgn @ ;
stmt -> iter ;
stmt -> { stmts } ;
stmt -> continue ;
stmt -> break ;
expr -> E ;
E -> E + T ;
E -> E - T ;
E -> T ;
T -> T * F ;
T -> T / F ;
T -> T % F ;
T -> F ;
F -> ( E ) ;
F -> num ;
F -> xiao ;
F -> id ;
F -> id [ expr ] ;
asgn -> left = expr ;
asgn -> left = funid ( funcs ) ;
funid -> id ;
funcs -> funcs , func ;
funcs -> func ;
func -> id ;
func -> num ;
left -> id ;
left -> id [ expr ] ;
iter -> for ( asgn @ M1 rel @ N4 inc ) N2 stmt ; iter -> while M1 ( rel ) M2 stmt ;
M1 -> $ ;
M2 -> $ ;
N1 -> $ ;
N2 -> $ ;
N3 -> $ ;
N4 -> $ ;
N5 -> $ ;
N6 -> $ ;
rel -> expr op expr ;
rel -> ! rel ;
rel -> rel o N3 rel ;
op -> < ;
op -> > ;
op -> <= ;
op -> >= ;
op -> == ;
o -> && ;
o -> || ;
inc -> left ++ ;
slct -> if ( rel ) M1 stmt N1 else M2 stmt ;
stmt -> printf ( str ) @ ;
stmt -> printf ( str , N5 ids ) @ ;
stmt -> scanf ( str , & id ) @ ;
补充说明:$表示空,@表示语义说明,详见代码。

相关文档
最新文档