《第八章代码生成》由会员分享,可在线阅读,更多相关《第八章代码生成(54页珍藏版)》请在金锄头文库上搜索。
1、第八章第八章 代代 码码 生生 成成 本章内容本章内容一个简单的代码生成算法一个简单的代码生成算法涉及存储管理,指令选择,寄存器分配涉及存储管理,指令选择,寄存器分配和计算次序选择和计算次序选择等基本问题等基本问题前端前端代代码码优优化化器器中间中间代码代码源程序源程序代码代码生成生成器器中间中间代码代码目标目标程序程序苑孪惰继棵惶蜜鹊祖费蒸播与革呜嗅柬犊调乌滋袭啄媚遍林囤并肚饶仆遂第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题8.1.1 目标程序目标程序可执行目标模块可执行目标模块可重定位目标模块可重定位目标模块允许程序模块分别编译允许程序模块分别编译调
2、用其它先前编译好的程序模块调用其它先前编译好的程序模块汇编语言程序汇编语言程序免去编译器重复汇编器的工作免去编译器重复汇编器的工作从教学角度,增加可读性从教学角度,增加可读性骆樊枕宛补棵瞩脐寅撬岁责查广杭般票逞遇曹弱拧踊棚辐裤捌距牙潮皮情第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题8.1.2 指令的选择指令的选择目标机器指令系统的性质决定了指令选择的目标机器指令系统的性质决定了指令选择的难易程度,指令系统的统一性和完备性是重难易程度,指令系统的统一性和完备性是重要的因素要的因素指令的速度和机器特点是另一些重要的因素指令的速度和机器特点是另一些重要的因素曝
3、哆禄厂罢纳带蚕碱玄斗你彤朵寄惨宵桥鬼早嗣炮齿苑将叉抒士彩钥德屋第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题若不考虑目标程序的效率,指令的选择是直若不考虑目标程序的效率,指令的选择是直截了当的。截了当的。三地址语句三地址语句x:=y+z(x x,y y和和z z都是静态分配)都是静态分配)MOVy,R0/*把把y装入寄存器装入寄存器R0*/ADDz,R0 /*z加到加到R0上上*/MOVR0, x/*把把R0存入存入x中中*/逐个语句地产生代码,常常得到低质量的代码逐个语句地产生代码,常常得到低质量的代码宁僧踞瓜驭缄索泉滚砍伎药几检载壤弱椽伴愚抑掩荔莎许车
4、滓奖翟歇臼蔷第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题语句序列语句序列 a:=b+cd:=a+e的代码如下的代码如下MOVb,R0ADDc,R0MOVR0, aMOVa,R0ADDe,R0MOVR0, d聋峨幸程板兼酶耸券专们茎气炙贞簧孜肥田浇誊犯官梭遗玫滦校痊贵戚姆第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题语句序列语句序列 a:=b+cd:=a+e的代码如下的代码如下MOVb,R0ADDc,R0MOVR0, aMOVa,R0-多余的指令多余的指令ADDe,R0MOVR0, d留吸哺完朽掘釜宣供钦鸡姿税炎韧艇贷
5、新雁匈摄狸碟行己商柄漳曰祸怜防第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题语句序列语句序列 a:=b+cd:=a+e的代码如下的代码如下MOVb,R0ADDc,R0MOVR0, aMOVa,R0-多余的指令多余的指令ADDe,R0-若若a不再使用,第三条也不再使用,第三条也MOVR0, d-多余多余战透惶翟箕再沙芥究焕鸦悲鄙猎吏废农扬刚葛胆顶崩弯沼篇茵幂贺跪白辞第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题8.1.3寄存器分配寄存器分配运算对象处于寄存器中的指令通常比运算对运算对象处于寄存器中的指令通常比运算对象处于
6、内存的指令要短一些,执行也快一些象处于内存的指令要短一些,执行也快一些寄存器分配寄存器分配选择驻留在寄存器中的一组变量选择驻留在寄存器中的一组变量寄存器指派寄存器指派挑选变量要驻留的具体寄存器挑选变量要驻留的具体寄存器星舱叫烹瓷疯袋瘁虽若涧柔谴欺搅阎骤管罕臼伴兹叔募糜都址虫吓之睁妈第八章代码生成第八章代码生成8.1 代码生成器的设计中的问题代码生成器的设计中的问题8.1.4计算次序的选择计算次序的选择某种计算次序可能会比其它次序需要较少的某种计算次序可能会比其它次序需要较少的寄存器来保存中间结果寄存器来保存中间结果熔忻臀裂警诱潮膀撕惦芬清讼羊傅末挤绚瞻毗催枕狙授京锣梧千皑烁烧画第八章代码生成第
7、八章代码生成8.2 目目 标标 机机 器器 8.2.1目标机器的指令系统目标机器的指令系统选择可作为几种微机代表的寄存器机器选择可作为几种微机代表的寄存器机器四字节组成一个字,有四字节组成一个字,有n个通用寄存器个通用寄存器R0, ,R1, ,Rn-1。二地址指令二地址指令op 源,目的源,目的MOV源传到目的源传到目的ADD源加到目的源加到目的SUB目的减去源目的减去源袭甸软印宅阻裔勺婚碟愈么晾耻射昆杂佯浙婶汕蛮吨株字淮吱棚束交凸径第八章代码生成第八章代码生成8.2 目目 标标 机机 器器 地址模式和它们的汇编语言形式及附加代价地址模式和它们的汇编语言形式及附加代价模式模式形式形式地址地址附
8、加代价附加代价绝对地址绝对地址 MM1寄存器寄存器RR0变址变址c(R)c+contents(R) 1间接寄存器间接寄存器* *Rcontents(R)0间接变址间接变址 * *c(R)contents(c+contents(R)1直接量直接量#cc 1铁永殃首倒酵迷彬考桑脸愁阿服玖睹狈傅售沾肘测围将油邮闪涎咬斤沁鸽第八章代码生成第八章代码生成8.2 目目 标标 机机 器器 指令实例指令实例MOVR0,MMOV4(R0),Mcontents(4+contents(R0)MOV* *4(R0),Mcontents(contents (4+contents(R0)MOV#1,R0贷粮硷烽救崇灯缠狮
9、歹落外裸举华燃煤请嫂膝滑炒氦刻啄缎凭脚规雄秘酶第八章代码生成第八章代码生成8.2 目目 标标 机机 器器 8.2.2指令的代价指令的代价指令代价取成指令代价取成1加上它的源和目的地址模式的加上它的源和目的地址模式的附加代价附加代价指令指令代价代价MOVR0,R11MOVR5,M2ADD#1, R32SUB4(R0),* *12(R1) 3须候谢蛔沪壤梢寥减若斋筒粘契话轻深劳涎输簇赶塔毋寂蛔渍尖钵再唐画第八章代码生成第八章代码生成8.2 目目 标标 机机 器器 a:=b+c,a、b和和c都静态分配内存单元都静态分配内存单元MOVb,R0ADDc,R0代价代价=6MOVR0,a螟遂代伸刽狭臃鸣琉泅
10、隐胎你冷钎走绩伴贱敲蜗僵旋徐驱厄信何篙蝗坯覆第八章代码生成第八章代码生成8.2 目目 标标 机机 器器 a:=b+c,a、b和和c都静态分配内存单元都静态分配内存单元MOVb,R0ADDc,R0代价代价=6MOVR0,aMOVb,aADDc,a代价代价=6莹表瑰上旱赌售挂在第蝇喻幸胚拾扬化峰正丘具荣刽奄块啮腺缄番走符血第八章代码生成第八章代码生成8.2 目目 标标 机机 器器 a:=b+c,a、b和和c都静态分配内存单元都静态分配内存单元若若R0,R1和和R2分别含分别含a,b和和c的地址,则的地址,则MOV* *R1,* *R0ADD* *R2,* *R0代价代价=2烤承裂趋奔旱募锁铁后渗册
11、仪彭最伺研个暇遏焚椅建乎力状他滤呵盛族瞻第八章代码生成第八章代码生成8.2 目目 标标 机机 器器 a:=b+c,a、b和和c都静态分配内存单元都静态分配内存单元若若R0,R1和和R2分别含分别含a,b和和c的地址,则的地址,则MOV* *R1,* *R0ADD* *R2,* *R0代价代价=2若若R1和和R2分别含分别含b和和c的值,并且的值,并且b的值在这个的值在这个赋值后不再需要,则赋值后不再需要,则ADDR2,R1MOVR1,a代价代价=3闰竣抽蹬夏衰仓介盾盔铀梭辫逝十陨抒彝朔堰在辆呵酷掺衣俊化费志磋洼第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图怎样为三地址语句序列生成
12、目标代码?怎样为三地址语句序列生成目标代码?begin|(1) prod:=0prod:=0;|(2) i:=1i:=1;|(3) t1:=4* *idobegin|(4) t2:=at1prod:=prod+ai*bi;|(5) t3:=4* *ii:=i+1|(6) t4:=bt3endwhilei=20|(7) t5:=t2* *t4end|(8) t6:=prod+t5|(9) prod:=t6|(10)t7:=i+1|(11) i:=t7|(12)ifi=20goto(3)龋竞贵酒弄叁抉堰粤犊棠梦炸黍葬泥菜妓以婿剿孵行篱痰摔贤镜企桨感民第八章代码生成第八章代码生成8.3 基本块和流图
13、基本块和流图8.3.1基本块基本块基本块基本块:连续的语句序列,控制流从它的开始:连续的语句序列,控制流从它的开始进入,并从它的末尾离开进入,并从它的末尾离开再用有向边表示基本块之间的控制流信息,就再用有向边表示基本块之间的控制流信息,就能得到程序的流图能得到程序的流图霉柯蓑出秀昂澳溶钧奸辉边冷槐貉漂与癣堡妆喧漆注奠岳寨龙绝镐正酋杉第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图三地址语句序列的三地址语句序列的划分基本块划分基本块首先确定所有的首先确定所有的入口语句入口语句序列的第一个语句是入口语句序列的第一个语句是入口语句能由条件转移语句或无条件转移语句转到的语句能由条件转移语句
14、或无条件转移语句转到的语句是入口语句是入口语句紧跟在条件转移语句或无条件转移语句后面的语紧跟在条件转移语句或无条件转移语句后面的语句是入口语句句是入口语句每个入口语句每个入口语句到下一个到下一个入口语句之前的语句入口语句之前的语句序列构成一个基本块序列构成一个基本块摩板幸芜给跟盖涨嘱褐且黑砰氨摧湃康哮按惨捂意藐佩呐鼠策峻锨伐呢谱第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图(1)prod:=0(2)i:=1(3)t1:=4* *i(4)t2:=at1(5)t3:=4* *i(6)t4:=bt3(7)t5:=t2* *t4(8)t6:=prod+t5(9)prod:=t6(10)t
15、7:=i+1(11)i:=t7(12) ifi=20goto(3)(1)prod:=0(2)i:=1(3)t1:=4*i(4)t2:=at1(5)t3:=4*I(6)t4:=bt3(7)t5:=t2*t4(8)t6:=prod+t5(9)prod:=t6(10)t7:=i+1(11)i:=t7(12)ifi=20goto(3)B1B2恶慷咆瓤汁掷桌势俏葫破跳瘤辖础撒脊女肾嚎疼方祝阵灿扩摄惕邓羡辖果第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图8.3.2基本块的变换基本块的变换三地址语句三地址语句x := y + zx := y + z引用引用y y和和z z并对并对x x定值定值
16、一一个个名名字字的的值值在在基基本本块块的的某某一一点点以以后后还还要要引引用的话,我们说这个名字在该点是用的话,我们说这个名字在该点是活跃活跃的的基本块的等价基本块的等价两个基本块计算一组同样的表达式两个基本块计算一组同样的表达式这些表达式的值分别代表同样的活跃名字的值这些表达式的值分别代表同样的活跃名字的值有很多等价变换可用于基本块有很多等价变换可用于基本块局部变换局部变换全局变换全局变换离掐取篱忆像手磋富输宗惧异敦啊氨芳烩刚葱罪袄倚酱蝗逊燥晴令殿异务第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图删除局部公共子表达式删除局部公共子表达式a:=b+ca:=b+cb:=a db:
17、=a dc:=b+cc:=b+cd:=a dd:=b删除死代码删除死代码定值定值x:=y+z以后不再引用,以后不再引用,则称则称x为死变量为死变量疼嗣喝胚动酮桑伊蛮钾烽毫淘号阑什当筛腰镇影查次灯朱决寞所纠叔动呼第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图交换相邻的独立语句交换相邻的独立语句t1:=b+ct2:=x+yt2:=x+yt1:=b+c当且仅当当且仅当x和和y都不是都不是t1,b和和c都不是都不是t2代数变换代数变换x:=x+0可以删除可以删除x:=x* *1可以删除可以删除x:=y*2改成改成x:=y* *y迷炙累南吧獭宋苟莉邻甄它冕游即体圆赫泥傲或鸳吝贵瓷技蛙昼隐帚
18、停冯第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图8.3.3流图流图把把控控制制流流信信息息加加到到基基本本块块集集合合,形形成成一一个个有有向图来表示程序向图来表示程序首结点首结点、前前驱驱、后继、后继听承膏替舀溅掩蓬痢眶尤坠寡艘碳雀双咎奇噬套凛减愿颅哄杉约组衡妆爸第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图什么是循环什么是循环?所有结点是所有结点是强连通强连通的的唯一的循环唯一的循环入口入口外循环和内循环外循环和内循环prod:=0i:=1t1:=4*it2:=at1t3:=4*It4:=bt3t5:=t2*t4t6:=prod+t5prod:=t6t7:=i
19、+1i:=t7ifi=20gotoB2B1B2篓炬骇衡晋毒桌拙人沧棒绕甫妈蔓乱岂返疟酌又酷促架养骋凳谱曼糯窍鼓第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图8.3.4下次引用信息下次引用信息为为每每个个三三地地址址语语句句x:=yopz决决定定x、y和和z的的下下次引用信息次引用信息i: x:=yopz.没有对没有对x的赋值的赋值j: :=x.没有对没有对x的赋值的赋值k: :=x弃挣破下鸥赘分巳术躲拔迂敞誉份田拙今埔附谰挠毛饼辐木借药擦型撵扼第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图8.3.4下次引用信息下次引用信息为为每每个个三三地地址址语语句句x:=yop
20、z决决定定x、y和和z的的下下次引用信息次引用信息i: x:=yopz.没有对没有对x的赋值的赋值j: :=x.没有对没有对x的赋值的赋值k: :=x虐获癸循损会卓袋馋虾灯玫梅隙随馅盾捉斜兔衬上掳翠柜蕾磅彤帅尽臂六第八章代码生成第八章代码生成8.3 基本块和流图基本块和流图对每个基本块从最后一个语句反向扫描到第对每个基本块从最后一个语句反向扫描到第一个语句一个语句,可以得到下次引用信息,可以得到下次引用信息i: x:=yopz.没有对没有对x的赋值的赋值j: :=x.没有对没有对x的赋值的赋值k: :=x册帕娟刁渡疯锡途胆嘴汲雀羽社墟继蔗岭砷咎淘林听锯渐饮韶瑞郴滦灯采第八章代码生成第八章代码生
21、成8.3 基本块和流图基本块和流图对每个基本块从最后一个语句反向扫描到第对每个基本块从最后一个语句反向扫描到第一个语句一个语句,可以得到下次引用信息,可以得到下次引用信息i: x:=yopz.没有对没有对x的赋值的赋值j: :=x.没有对没有对x的赋值的赋值k: :=x利利用用下下次次引引用用信信息息,可可以以压压缩缩临临时时变变量量需需要要的空间的空间村楔批嗣萄甸危捧鸣黎颐新藏塘捡浇谩漫都赌拘弓琉偿驼背纸歧蕴谤估柴第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器依次考虑基本块的每个语句,为其产生代码依次考虑基本块的每个语句,为其产生代码假假定定三三地地址址语语句句
22、的的每每种种算算符符都都有有对对应应的的目目标标机器算符机器算符假定计算结果留在寄存器中尽可能长的时间假定计算结果留在寄存器中尽可能长的时间, ,除非:除非:该寄存器要用于其它计算该寄存器要用于其它计算,或者,或者到基本块结束到基本块结束孝丢言硫廊挛咯疼坯筒侥痹写绥颜捣穷疫图随译赡拎频喷臀苗鄙棕架砚别第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器在没有收集全局信息在没有收集全局信息前,暂且以基本块为前,暂且以基本块为单位来生成代码单位来生成代码prod:=0i:=1t1:=4*it2:=at1t3:=4*It4:=bt3t5:=t2*t4t6:=prod+t5pr
23、od:=t6t7:=i+1i:=t7ifi=20gotoB2B1B2凤昏圃筒膝棵瘁远倪如循奖龄炽捍担聊遮啪貌酗厉猿傻齐磷徒宝默捡拢宰第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器8.4.1寄存器描述和地址描述寄存器描述和地址描述例:对例:对a:=b+c如果寄存器如果寄存器Ri含含b,Rj含含c,且,且b此后不再活跃此后不再活跃产生产生ADDRj,Ri,结果,结果a在在Ri中中如果如果Ri含含b,但,但c在内存单元,在内存单元,b仍然不再活跃仍然不再活跃产生产生ADDc,Ri,或者,或者MOVc,RjADDRj,Ri若若c的值以后还要用的值以后还要用, ,第二种代码
24、比较有吸引力第二种代码比较有吸引力旱又袱庸哈荚娃抄饰抚堰务鲜爽驻硬碗炊淆淄油刮料死谋琢曼百陇详剧撼第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器在代码生成过程中,需要跟踪寄存器的内容和在代码生成过程中,需要跟踪寄存器的内容和名字的地址名字的地址寄存器描述记住每个寄存器当前存的是什么寄存器描述记住每个寄存器当前存的是什么在在任任何何一一点点,每每个个寄寄存存器器保保存存若若干干个个( (包包括括零零个个) )名字的值名字的值名名字字的的地地址址描描述述记记住住运运行行时时每每个个名名字字的的当当前前值可以在哪个场所找到值可以在哪个场所找到这这个个场场所所可可以以是是
25、寄寄存存器器、栈栈单单元元、内内存存地地址址、甚甚至是它们的某个集合至是它们的某个集合这些信息可以存于符号表中这些信息可以存于符号表中这两个描述在代码生成过程中是变化的。这两个描述在代码生成过程中是变化的。船喧膨洁缅仿梁兰瘟软惭涕闲午复惮袱烤随限呀渔限恫认雹邓地坤顶池潞第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器8.4.2 代码生成算法代码生成算法对每个三地址语句对每个三地址语句x:=yopz调用函数调用函数getreg决定放决定放y op z计算结果的场所计算结果的场所L查查看看y的的地地址址描描述述, ,确确定定y值值当当前前的的一一个个场场所所y .如如果
26、果y的的值值还还不不在在L中中,产产生生指指令令MOVy ,L产产生生指指令令opz ,L,其其中中z 是是z的的当当前前场场所所之一之一如如果果y和和/ /或或z的的当当前前值值不不再再引引用用,在在块块的的出出口口也也不不活活跃跃,并并且且还还在在寄寄存存器器中中,那那么么修修改改寄寄存器描述存器描述千蹬营娶迄卒甥赚阶点番昼噪愚擎品奄躲年佳英链媚炙堡萄妈程称锚跟令第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器8.4.3 寄存器选择函数寄存器选择函数函数函数getreg返回保存返回保存x:=yopz的的x值的场所值的场所L如如果果名名字字y在在R R中中,这这个
27、个R R不不含含其其它它名名字字的的值值, ,并并且且在在执执行行x:=yopz后后y不不再再有有下下次次引引用用,那那么么返返回回这个这个R R作为作为L。否则,返回一个空闲寄存器,如果有的话否则,返回一个空闲寄存器,如果有的话否否则则,如如果果x在在块块中中有有下下次次引引用用,或或者者op是是必必须须用用寄寄存存器器的的算算符符,那那么么找找一一个个已已被被占占用用的的寄寄存存器器R(可能产生可能产生MOVR,M指令,并修改指令,并修改M的描述的描述)否否则则,如如果果x在在基基本本块块中中不不再再引引用用,或或者者找找不不到到适当的被占用寄存器,选择适当的被占用寄存器,选择x的内存单元
28、作为的内存单元作为L。挎栅屑仍慧邪碎灰阉扔宝熄尼全怀鉴芹墟瞒涉腊癸狰峡袋虹锦峡震努诵酣第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器赋值语句赋值语句d:=(a b)+(a c)+(a c)编译产生三地址语句序列:编译产生三地址语句序列:t1:=a bt2:=a ct3:=t1+t2d:=t3+t2 剪铅沼谗畜打喧底曰捉照轻严腺啃摈盈磨藉孔恿仗哮宁铁盖涅佃货顾屯沤第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器语语句句 生成的代码生成的代码 寄存器描述寄存器描述 名字地址描述名字地址描述 寄存器空寄存器空 t1:=a b MOVa,R0S
29、UBb,R0 R0含含t1 t1在在R0中中 t2:=a cMOVa,R1SUBc,R1R0含含t1R1含含t2t1在在R0中中t2在在R1中中t3:=t1+t2 ADDR1,R0 R0含含t3R1含含t2t3在在R0中中t2在在R1中中 d:=t3+t2 ADDR1,R0 R0含含dd在在R0中中 MOVR0,d d在在R0和和内内存存中中殉诌联贡尤蕾拳怎诅邮卉利拌嗡镍焉熊勺诛瀑胎末脑弹拙满譬俺息蔬疥墅第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器前三条指令可以修改,使执行代价降低前三条指令可以修改,使执行代价降低MOVa,R0MOVa,R0SUBb,R0MOV
30、R0,R1MOVa,R1SUBb,R0SUBc,R1SUBc,R1.渠淆目寨辜头纯撂荣卤皿义仁嚣肤葫空靡委蛇考袒娟惩撇辩枷娩郸晶毗卓第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器8.4.4 为为变址和指针变址和指针语句产生代码语句产生代码变变址址与与指指针针运运算算的的三三地地址址语语句句的的处处理理和和二二元元算符的处理相同算符的处理相同 悦枣渭顺啡政糖焊瞅滴险划倔瓷佰屉灶霸货鹿捶烤兢姜姚钨由忻查框犯分第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器8.4.5 条件语句条件语句实现条件转移有两种方式实现条件转移有两种方式根根据据寄寄存
31、存器器的的值值是是否否为为下下面面六六个个条条件件之之一一进进行分支:负、零、正、非负、非零和非正行分支:负、零、正、非负、非零和非正用用条条件件码码来来表表示示计计算算的的结结果果或或装装入入寄寄存存器器的的值是负、零还是正值是负、零还是正标艺痒烫蛛喜吨撅揪峻研若查库献磁寄褐匝赊米幸碳谱擞潭三靡饵忙拧嗣第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器根据寄存器的值是否为下面六个条件之一进行根据寄存器的值是否为下面六个条件之一进行分支:负、零、正、非负、非零和非正分支:负、零、正、非负、非零和非正例如:例如:ifxygotoz把把x减减y的值存入寄存器的值存入寄存器
32、R,如果如果R的值为负,则跳到的值为负,则跳到z谁初夸植吏居二暇泞迄椰晕拜醚呢绸鳖榷质水匙服补辅爪桨烁讨肛予固遂第八章代码生成第八章代码生成8.4 一个简单的代码生成器一个简单的代码生成器用条件码的例子用条件码的例子ifxygotozx:=y+z的实现:的实现:ifx0gotozCMPx,y的实现:的实现:CJzMOVy, R0ADDz,R0MOVR0,xCJz势娱茧燥虽墓酞逢胳案阴慰渝历弊赐陨医漓忽沈碰枚效香义叭拈稍幼窥歇第八章代码生成第八章代码生成本本章章要要点点代代码码生生成成器器设设计计中中的的主主要要问问题题:存存储储管管理理、计计算算次次序序的的选选择择、寄寄存存器器的的分分配配、
33、指指令令的的选选择等。择等。目目标标机机器器几几种种常常用用的的地地址址模模式式和和一一些些常常用用的的指令。指令。基本块和程序流图。基本块和程序流图。简单的代码生成算法。简单的代码生成算法。牡居腕自抬庭谗苦夸肥权诉医抚陕遭送捅搏萍垫凋孟腥荚枕歇紊陪松索樟第八章代码生成第八章代码生成例例 题题 1在在SPARC/SUNOS上,经某编译器编译,程序的结果上,经某编译器编译,程序的结果是是120。把第。把第4行的行的abs(1)改成改成1的话,则程序结果是的话,则程序结果是1intfact()staticinti=5;if(i=0)return(1);elsei=i-1;return(i+abs(
34、1)*fact();main()printf(factorof5=%dn,fact();孰猴烬昭坍搜顷警讯沫晤价书梆媒驹卷墩侯荒碟舟拽梅桃狼帛款密氛知比第八章代码生成第八章代码生成例例 题题 2下面的程序在下面的程序在X86/Linux机器上编译后的运行结机器上编译后的运行结果是果是7,而在,而在SPARC/SUNOS机器上编译后的运机器上编译后的运行结果是行结果是6。试分析运行结果不同的原因。试分析运行结果不同的原因。main()longi;i=0;printf(%ldn,(+i)+(+i)+(+i);妮萎剁惺逻趟镊毁物杂峪楷毁握砷夏浸吠寻篓摧蔡瞳苍锁妈漆弥管颜案锈第八章代码生成第八章代码生
35、成例例 题题 2按一般的代码生成,按一般的代码生成,i=i+1的计算结果保留在的计算结果保留在寄存器中,因此这三个寄存器中,因此这三个i=i+1的计算次序不会的计算次序不会影响最终的结果。结果应该是影响最终的结果。结果应该是6。+:=i+i1:=i+i1:=i+i1铱葱挽呜攫婪银砍糯毅激修内勾荐丑衙瞧罢恤厄垮汗叹馆办开款氖碍圃核第八章代码生成第八章代码生成例例 题题 2按一般的代码生成,按一般的代码生成,i=i+1的计算结果保留在的计算结果保留在寄存器中,因此这三个寄存器中,因此这三个i=i+1的计算次序不会的计算次序不会影响最终的结果。结果应该是影响最终的结果。结果应该是6。结果是结果是7
36、7的话,一定是的话,一定是某个某个i=i+1的结果未保的结果未保留在寄存器中留在寄存器中。上层上层计算对它的引用落在计算对它的引用落在计算另一个计算另一个i=i+1的的后面后面+:=i+i1:=i+i1:=i+i1桥烦疽转胆砾殖禽忆檀老刷厘喜滇敛掳骸徘曲麦摩缚边烩胃骂旦瞬宪挽炙第八章代码生成第八章代码生成例例 题题 2如果机器有如果机器有INC指令的话,编译器极可能产生指令的话,编译器极可能产生一条一条INC指令来完成指令来完成i=i+1X86/Linux机器上果真是这么做的机器上果真是这么做的+:=i+i1:=i+i1:=i+i1醒美坑惊既液征凌疗氖瑚冯搐奥迄攒耘吩悟怂痰压朗山冬硷辗鹏姐咐拧
37、拍第八章代码生成第八章代码生成例例 题题 2将表达式改成将表达式改成(+i)+(+i)+(+i),结果会怎样?结果会怎样?+:=i+i1+:=i+i1:=i+i1斡佬浸伏魁潘扫糠憎粥踊面族诱凄价蛆皱页追楼榔气飞茶皋瀑莆厕闹窜冷第八章代码生成第八章代码生成例例 题题 2将表达式改成将表达式改成(+i)+(+i)+(+i),结果会怎样?结果会怎样?在在SPARC/SUNOS机器上的结果仍然是机器上的结果仍然是6。在在X86/Linux机器上的结果是机器上的结果是9。+:=i+i1+:=i+i1:=i+i1煞码载刺甸鸵周些谁允圆梯辈剂甥高鸳傈夜外羌淬迟揣库仲右盘棚捂昏寻第八章代码生成第八章代码生成例
38、例 题题 3下面下面C语言程序如下语言程序如下,运行时输出运行时输出105,为什么?为什么?main()longi;i=10;i=(i+5)+(i=i*5);printf(%dn,i);述毅崔夸珍革萤乏撬秒逻饼疚顺势殿舌娃餐记拘恬垮塞锰综帝骸殷杰殖庇第八章代码生成第八章代码生成例例 题题 3下面下面C语言程序如下语言程序如下,运行时输出运行时输出105,为什么?为什么?main()longi;i=10;i=(i+5)+(i=i*5);printf(%dn,i);表达式表达式表达式表达式表达式表达式需需2个个R需需3个个R需需几个几个R屁撒癸股康眼病粕卜著摆文霹立摹里蔓丁壮言乱膏琐恳豢胜霄儿级炕康张第八章代码生成第八章代码生成习习题题第一次:第一次:8.4(只为(只为8.1(e)生成代码)生成代码)横须绚愈欲验忽株钙目越税星嗽恤藏艰痛络隘笔笑曝厉窘直暮寅败灼搅础第八章代码生成第八章代码生成