代码生成.

Slides:



Advertisements
Similar presentations
阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
Advertisements

平面构成 第六章 平面构成形式与法则 — 破规与变异. 第七章 平面构成形式与法则 — 破规与变异 破规与变异构成的形式、有下列四类: 一、特异构成 特异构成。其表现特征是,在普遍相同性质的事物 当中,有个别异质性的事物,便会立即显现出来。
XX啤酒营销及广告策略.
第十五章 控制方法.
7.4 用矩阵初等行变换 解线性方程组 主要内容: 一.矩阵的行初等变换 二.用行初等变换求逆矩阵 三.用矩阵法求线性方程组.
2017年3月5日 单片机原理与应用 背景知识调查.
第十章 依赖于机器的优化 在指令级并行的机器上,程序的运行速度依赖于下面几个因素
程序的转换与机器级表示 主要教学目标 了解高级语言与汇编语言、汇编语言与机器语言之间的关系
x86/Pentium指令系统 x86寻址方式 1.比例变址寻址方式 (Scaled Indexed Addressing)
材料金相实验与显微组织观察 F 组长:李霄 组员:王猛 徐晗 张天龙 张腾 王曦 张浩舵.
第1讲 实验环境.
大连理工大学软件学院 软件工程系 赖晓晨 计算机组成与结构 大连理工大学软件学院 软件工程系 赖晓晨
北师大版七年级数学 5.5 应用一元一次方程 ——“希望工程”义演 枣庄市第三十四中学 曹馨.
海洋存亡 匹夫有责 ——让我们都来做环保小卫士 XX小学三(3)班.
3.3.5 程序控制指令 控制转移指令分为: 转移指令 循环控制指令 调用和返回指令 中断指令.
第5章 循环与分支程序设计  循环程序设计  分支程序设计.
汇编语言程序设计 Assembly Language Programming
逆向工程-汇编语言
代码生成.
第2章 汇编语言与汇编程序 ——8086/8088指令系统 mov ax,12h call display Jmp 1234h.
EBNF 请用扩展的 BNF 描述 C语言里语句的结构; 请用扩展的 BNF 描述 C++语言里类声明的结构;
第六章 运行时存储空间的组织和管理 术语 本章内容 讨论一个活动记录中的数据布局 程序执行过程中,所有活动记录的组织方式 过程的活动
第3章 寻址方式 罗文坚 中国科大 计算机学院
编译原理与技术 2018/11/30 《编译原理与技术》讲义.
第八章 代 码 生 成 本章内容 一个简单的代码生成算法 涉及存储管理,指令选择,寄存器分配和计算次序选择等基本问题 前端 代 码 优 化
基本的”防”黑客技术 Basic” ” Hacker Technique
7.1 机器指令 7.2 操作数类型和操作类型 7.3 寻址方式 7.4 指令格式举例 7.5 RISC 技术.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
逆向工程-汇编语言
动态规划(Dynamic Programming)
CPU结构和功能.
條件處理.
《编译原理与技术》 期末复习 计算机科学与技术学院 郑启龙 李 诚 25/12/2018.
第7章 在C/C++中使用汇编 罗文坚 中国科大 计算机学院
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
C语言程序设计 主讲教师:陆幼利.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
第2章 80x86计算机组织  计算机系统  存储器  中央处理机  外部设备.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月13日.
工业机器人知识要点解析 (ABB机器人) 主讲人:王老师
第5章 循环与分支程序设计  循环程序设计  分支程序设计.
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
代码优化.
第十章 优化 网上教学系统: : 编译原理 第十章 优化 网上教学系统: : 编译原理.
信号量(Semaphore).
美麗的西子湖.
第4章 Excel电子表格制作软件 4.4 函数(一).
本节内容 内存复制指令 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第九节 赋值运算符和赋值表达式.
目标代码生成.
虚拟机加密,是把源程序的X86指令变成自定义的伪指令,执行时内置在保护程序中的VM就会启动,读取伪指令,然后解析执行
College of Computer Science & Technology
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
微机原理与接口技术 ——8086微处理器 西安邮电大学 计算机学院 范琳.
第7章 代码优化 学习目标: 掌握:基本块的划分、基本块的DAG优化 理解:什么是局部优化、循环优化、全局优化 了解:循环优化技术.
临界区问题的硬件指令解决方案 (Synchronization Hardware)
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
3. 逻辑运算指令 A、简单逻辑操作指令 CLR A. (不影响CY、AC、 OV标志) CPL A
本节内容 通用寄存器 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Do While 迴圈 東海大學物理系‧資訊教育 施奇廷.
微机原理与接口技术 西安邮电大学计算机学院 宁晓菊.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
第四节 向量的乘积 一、两向量的数量积 二、两向量的向量积.
编译原理 第十一章 代码生成 编译原理.
大数据搜索挖掘实验室 第五章 子程序设计 张华平 副教授 博士 Website: 大数据搜索挖掘实验室
嵌入式Linux编程环境.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
Presentation transcript:

代码生成

代码生成 代码生成的输入 -各种中间代码形式 目标代码与目标机器模型 简单的代码生成器 基本块DAG图及代码生成

目标代码 绝对地址目标代码 可重定位的目标 - linker/loader 汇编代码 - assembler

目标机器模型 指令形式 op 源,目的 寻址模式 - 绝对地址:op M, R  R op (M)R - 寄存器:op R1,R2  R2 op R1 R2 - 变址:op R1,c(R2) (c+R2) op R1 (c+R2) - 间接变址、间接寄存器 - 直接量 op $C, R  R + C  R

简单代码生成器 寄存器描述 记录寄存器的使用情况,即某寄存器中存放的是哪(些)个名字(变量)的值。 名字地址描述 名字(变量)的当前值的存放场所,如放在寄存器或主存(数据区)或者栈里等。

简单代码生成器(续) 代码生成算法 对基本块中三地址代码,p: x := y op z, 1)调用函数getReg( ),返回存放计算结果的场所L(一般为寄存器R,也可能是存储单元); 2)若y的值不在L中,产生指令:mov y’, L (查y的名字地址描述获得y值的存放场所y’); 3)产生指令:op z’,L ( z’是z值的存放场所),修改x的名字描述和相关寄存器描述; 4)若y和/或z在p之后不再引用、出口不活跃且其值在寄存器中,则修改其相应寄存器和名字地址描述; 5)在块出口处,将所有活跃名字值刷新到相应存储单元。

简单代码生成器(续) -函数getReg(p:x := y op z): 返回计算结果存放场所L, 1)若某寄存器R仅含y的值且p后不再引用和不活跃,则返回R;(好处是可以省掉装载y值的指令mov y’,L) 2)返回某个空闲寄存器R; 3)若x必须使用寄存器,则此时“抢占”某个寄存器R。 查看R的描述,如果名字a的值在R中则产生转储指令mov R,Ma (Ma:a的存储单元),并修改相应的描述;(关键是如何抢占及剥夺哪些名字的寄存器使用权) 4)使用x的存储单元

e.g.1 简单代码生成 三地址码序列: t := a – b u := a + c v := t + u w:= v + u 可用寄存器R0,R1 初始,名字a、b和c的值均在相应存储单元中

e.g.1 简单代码生成 TAC 目标代码 REG NAME t:=a-b mov a, R0 sub b, R0 R0含t t在R0 u:=a+c mov a, R1 R0含t t在R0 add c, R1 R1含u u在R1 v:=t+u add R1, R0 R0含v v在R0 R1含u u在R1 w:=v+u add R1, R0 R0含w w在R0

其它语句的代码生成 语句 i 在Ri i 在Mi i 在栈中 a := b[i] mov b(Ri),R mov Mi,R mov Si(bp),R mov b(R),R mov b(R),R a[i] := b mov b,a(Ri) mov Mi,R mov Si(bp),R mov b,a(R) mov b,a(R) Si是i在栈中偏移,bp是当前活动记录基址。 指针操作语句:a := * b *a := b

转移语句 goto X  JMP X’ if x op y goto z - 根据寄存器内容是否满足以下条件: 负、零、正、非负、非零、非正 如 if x < y goto z : y – x  R 判别R非负(实施转移) - 根据条件码转移 如 if x < y goto z : cmp x, y jg z // 若y > x则转z

AT&T汇编简介

语法 INSTR Source, Dest e.g. movl (%ecx), %eax addl $1, %edx

前缀与后缀 % -- 寄存器前缀,如 %eax, %ebp $ -- 立即数前缀,如 , $100(十进制), $0x99(十六进制) $ -- 立即数前缀,如 , $100(十进制), $0x99(十六进制) 后缀 l , w , b -- 操作数大小,对应 long, word 和 byte, 如, movl %ebx, %ecx movb %bl, %al

内存寻址方式 section : disp ( base, index, scale ) 计算方式如下: base + index * scale + disp section/disp/index/scale(包括base) 均可缺省。section用于实模式下。如, addl (%ebx,%ecx,0x2), %edx  (%ebx+%ecx*0x2)+%edx %edx subl 0x20( %eax,%ecx,0x4), %ebx  %ebx - (%eax+%ecx*0x4+0x20) %ebx

内存寻址方式 leal (%ebx, %ecx) , %eax  %ebx + %ecx  %eax 这里scale缺省为1。scale 和 disp 中的立即数不加前缀$。

常用汇编指令 addl , subl , movl , sall pushl , popl , leave , ret leal , nop , incl jmp , jle 等条件转移指令

C语句 i = i * 10 对应汇编码 movl -4(%ebp),%edx // 取变量i的值到寄存器%edx movl %edx,%eax sall $2,%eax // 左移寄存器%eax 2位, %eax == 4 * i addl %edx,%eax // %eax == 5 * i leal 0(,%eax,2),%edx // %eax * 2  %edx, %edx == 10 * i // 为何不用 sall $1, %eax movl %edx,-4(%ebp) // 10 * i  i

e.g. 2 ++ 问题 main() { long i; i = 0; //printf("%ld\n", (i=i+1)+(i=i+1)+(i=i+1)); case 1 //printf("%ld\n", (++i)+(++i)+(++i)); case 2 //printf("%ld\n", (i++)+(i++)+(i++)); case 3 return 0; }

case 1 case 2 case 3 movl -4(%ebp),%eax movl -4(%ebp),%edx addl %edx,%eax movl %eax,%edx addl -4(%ebp),%edx pushl %edx incl -4(%ebp) pushl $.LC0 call printf movl $0,-4(%ebp) movl -4(%ebp),%edx incl %edx movl %edx,%eax movl %eax,-4(%ebp) movl %edx,%ecx movl %ecx,-4(%ebp) addl %ecx,%eax pushl %eax pushl $.LC0 call printf movl $0,-4(%ebp) incl -4(%ebp) movl -4(%ebp),%eax movl -4(%ebp),%edx addl %edx,%eax addl -4(%ebp),%eax pushl %eax pushl $.LC0 call printf

基本块的DAG图示 基本块内优化变换 合并已知量 删除冗余运算-公共子表达式 删除死代码

基本块DAG构造 (不考虑别名、数组或指针) 对于每条语句:x := y op z (1)分别寻找代表y或z的当前值的结点,若没有的话,构造它们的初始结点; (2)利用已有的算符op的结点或新建一个op结点(左、右子树分别标记为y和z),将x标记在旁边; (3)如果x在其他结点边上有标记(x0-x的初始值除外),则去除这个标记; (4)x := y ,不必建立新结点而将x标记在y对应的结点旁。

基本块DAG构造 * t1 i0 4 t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) * t1 4 i0

基本块DAG构造 * t2 t1 a i0 4 =[] t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := I + 1 i := t7 if i <= 20 goto (1) =[] t2 * t1 a 4 i0

基本块DAG构造 * t2 t1,t3 a i0 4 =[] t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) =[] t2 * t1,t3 a 4 i0

基本块DAG构造 * t4 t2 t1,t3 a b 4 i0 =[] =[] t1 := 4 * i t2 := a [ t1 ] t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) =[] t4 =[] t2 * t1,t3 a b 4 i0

基本块DAG构造 t5 t4 t2 * t1,t3 a b 4 i0 * =[] =[] t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) t5 * =[] t4 =[] t2 * t1,t3 a b 4 i0

基本块DAG构造 t6 t5 prod0 t4 t2 * t1,t3 a b 4 i0 + * =[] =[] t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) + t6 t5 prod0 * =[] t4 =[] t2 * t1,t3 a b 4 i0

基本块DAG构造 t6,prod t5 prod0 t4 t2 * t1,t3 a b 4 i0 + * =[] =[] t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) + t6,prod t5 prod0 * =[] t4 =[] t2 * t1,t3 a b 4 i0

基本块DAG构造 t6,prod t5 prod0 t4 t2 + t7 * t1,t3 a b 4 i0 1 + * =[] =[] t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) + t6,prod t5 prod0 * =[] t4 =[] t2 + t7 * t1,t3 a b 4 i0 1

基本块DAG构造 t6,prod t5 prod0 t4 t2 + t7,i * t1,t3 a b 4 i0 1 + * =[] =[] t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) + t6,prod t5 prod0 * =[] t4 =[] t2 + t7,i * t1,t3 a b 4 i0 1

基本块DAG构造 t6,prod t5 (1) prod0 <= t4 20 t2 + t7,i * t1,t3 a b 4 i0 1 t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) + t6,prod t5 (1) prod0 * <= =[] t4 20 =[] t2 + t7,i * t1,t3 a b 4 i0 1

基本块DAG构造 t1 := 4 * i t2 := a [ t1 ] t3 := 4 * i t4 := b [ t3 ] t5 := t2 * t4 t6 := prod + t5 prod := t6 t7 := i + 1 i := t7 if i <= 20 goto (1) t1 := 4 * i t2 := a [ t1 ] t4 := b [ t1 ] t5 := t2 * t4 prod := prod + t5 i := i + 1 if i <= 20 goto (1) DAG优化后

基本块DAG构造 特殊情况下(副作用)注销节点-- 数组元素 指针访问 过程调用 多变量共享存贮

基本块DAG构造 x := a[ i ] x := a[ i ] a[ j ] := y z := x z := a[ i ] 但如果 在 i=j 且 a[i] ≠ y时,变换前后语义不等价。 解决方案:在构造a[ i ]或a[ j ]时,注销所有[]=或=[] 节点,即不利用已有节点(做为公共子表达式), 而构造一个新的节点。

由DAG生成代码 DAG中节点重新排序(计算次序)- 启发式排序算法 树最优代码生成(略)

DAG启发式排序算法 while 还有未列出的内部节点 do { 选一个没有列出的内部节点n,其所有父节点均已列出; 列出 n; while n的最左子节点m的所有父节点均已列出而且m不是叶子节点 do { 列出 m; n := m; } 列出节点次序的逆序即为节点的最终计算次序。

e.g. DAG节点排序 计算次序:8 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 * + - a b e c 1 2 3 4 5 6 7 8 9 10 11 12 计算次序:8 6 5 4 3 2 1