C编译器剖析_6.3.1 汇编代码生成_由中间指令产生汇编代码的主要流程

C编译器剖析_6.1 汇编代码生成_简介 6.1 汇编代码生成简介     历经词法分析、语法分析、语义检查和中间代码生成阶段,我们终于来到了“目标代码生成阶段”,由于UCC编译器的目标代码即为32位x86汇编代码,因此我们就把本章称为“汇编代码生成”。UCC编译器中的大部分源代码都适用于Windows和Linux平台,但Windows平台上缺省的汇编器支持Intel风格的x86汇编代码,而Linux平台默认的汇编器则采用AT&T风格的 阅读详情

6.3.1  由中间指令产生汇编代码的主要流程

    在这一小节,我们可把关注的焦点放在“如何把某条中间代码翻译成汇编代码”上。UCC编译器的中间代码是如下所示的四元式,包括运算符和3个操作数。

         <运算符opcode,目的操作数DST,源操作数SRC1,源操作数SRC2>

    当然有些中间代码只需要用到opcode和DST就可以了,例如,无条件跳转指令“goto  BB2;”就不需要SRC1和SRC2。为了便于汇编代码的生成,UCC编译器在ucl\X86Linux.tpl中定义了许多汇编指令的模板。在X86平台上,无条件跳转指令的汇编指令为jmp,对应的指令模板如下所示:

         //无条件跳转

TEMPLATE(X86_JMP,     "jmp  %0")

    其中,X86_JMP是模板”jmp  %0”的编号,通过编号可找到对应的模板。模板中的“%0”充当占位符的作用,代表第0个操作数,即目的操作数DST,在汇编代码生成时,“%0”会被目的操作数DST所替代;而”%1”代表第1个操作数,即源操作数SRC1,“%2”代表第2个操作数,即源操作数SRC2。图6.3.1第29至31行的宏DST、SRC1和SRC2分别表示中间指令inst里的这3个操作数。假设跳转的目标是BB2,则根据模板“jmp  %0”,我们可产生汇编指令“jmp  BB2”。       

    下面,我们来举例介绍一下,如何由中间指令的运算符opcode出发,找到对应的汇编指令模板号。在中间代码层次,UCC编译器用ADD来表示加法指令,但在汇编层次,整数加法和浮点数加法对应的汇编指令是不一样的,如图6.3.1第22至25行所示。为了能通过中间代码的运算符ADD,快速地找到对应的汇编指令模板编号,ucl\X86Linux.tpl中的各模板是按一定顺序排列的。例如,当我们要进行两个double类型浮点数的加法运算时,其中间指令里的运算符opcode为ADD,类型为DOUBLE,通过第1至15行的函数TypeCode,我们可得到DOUBLE对应的类型编码为F8。以ADD和F8作为宏参数,通过第27行的宏ASM_CODE(),我们就可得到对应的模板号X86_ADDF8,如图6.3.1第26行所示。


图6.3.1 由中间指令到汇编代码的流程

C编译器剖析_6.3.6 汇编代码生成_为“取地址”产生汇编指令 6.3.6  为“取地址”产生汇编指令     在这一小节中,我们来讨论一下以下两条中间指令的翻译:     (1)取地址指令               例如 ,表示取number的地址并保存到临时变量t0中     (2)对象清零指令             例如,表示把arr所占16字节的内存清零     我们先举一个例子来说明,对于图6.3.14第4行局部数组arr的初 阅读详情

相关推荐

C编译器剖析_6.3.3 汇编代码生成_为跳转指令产生汇编代码

6.3.3        为跳转指令产生汇编代码     在这一小节中,我们要为“有条件跳转”、“无条件跳转”和“间接跳转”产生相应的汇编指令。中间指令的四元式如下所示:             (1) 有条件跳转,例如“if (a                         ////////对应的汇编代码//////////             movl  a, %ea

SheIsC的专栏 2317

C编译器剖析_6.3.5 汇编代码生成_为类型转换产生汇编代码

6.3.5  为类型转换产生汇编代码     在这一小节中,我们来讨论一下整型和浮点型之间的类型转换。有些类型转换并不需要在汇编层次进行数据转换,例如int和unsigned  int之间的转换只是改变了表达式的类型,对数据本身并无影响,以下表达式“(unsigned int) a”对应的二进制数据为0xFFFFFFFF,而表达式“a”对应的二进制数据也为0xFFFFFFFF。但对相同内容的二进

SheIsC的专栏 2029

C编译器剖析_6.3.4 汇编代码生成_为函数调用与返回产生汇编代码

6.3.4        为函数调用与返回产生汇编代码     在这一小节中,我们来讨论一下如何为函数调用和函数返回生成汇编代码。函数调用对应的中间指令如下所示:          //中间指令的四元式:              让我们先熟悉一下C函数的调用约定CallingConvention,我们需要把参数从右向左入栈(即从argn到arg1依次入栈),不妨记这些参数所占用的总内

SheIsC的专栏 1893

C编译器剖析_6.2 汇编代码生成_寄存器的管理

在计算机中,CPU的速度比内存的速度快得多,编译器应尽量有效地利用寄存器资源,减少对内存的不必要访问,从而提高由编译器生成的汇编代码的运行速度。在中间代码生成阶段,UCC编译器用临时变量t来存放形如“t: a+b;”的公共子表达式的值;到了汇编代码生成时,UCC编译器会尽可能地把这些公共子表达式的值存放在寄存器,当需要再次重用时,就可以直接由相应的寄存器中得到。不过,CPU中寄存器的资源是很有限的

SheIsC的专栏 1703

C编译器剖析_5.3.1 中间代码生成及优化_If语句和复合语句的翻译

5.3.1   If语句和复合语句的翻译     我们先简单回顾一下对布尔表达式的翻译,我们通过调用TranslateBranch函数来产生跳转指令,从而实现布尔表达式的语义。在使用函数TranslateBranch(expr, bt, bn)时,有这么两个约定:     (1) 当expr为真时,跳往bt基本块;     (2) 紧随“函数TranslateBranch所生成的跳转指令”之

SheIsC的专栏 2050

C编译器剖析_1.4 UCC编译器预览_UCC的使用

1.4.1  UCC的使用     通过第1.3节的例子ucc\examples\sc,我们对如何根据语言的文法来编写语法分析器,建立语法树,之后在语法树的基础上生成中间代码有了一个感性的直观认识。当然,光有这些中间代码,C程序员还不能得到其所要的计算结果。C编译器还要由中间代码产生汇编代码。在剖析UCC编译器前,让我们先熟悉一下UCC编译器的使用。UCC编译器的大部分代码都是用标准C语言并调用

SheIsC的专栏 4600

C编译器剖析_5.3.2 中间代码生成及优化_switch语句的翻译

5.3.2.Switch语句的翻译    在这一小节中,我们来讨论一下switch语句的翻译,switch语句的产生式如下所示。 SwitchStatement:                    switch( expr ) statement    当C程序员编写出如下代码时,UCC编译器会在语义检查阶段进行报错“error:The  break shall  appear  in

SheIsC的专栏 2262

C编译器剖析_5.4.2 中间代码生成及优化_基本块的合并

5.4.2  基本块的合并     我们在第5.4.1节时给出了由基本块构成的双向链表和控制流图,为阅读方便,我们这里再次给出“图5.1.4 基本块的静态结构和动态结构”。在这一小节中,我们试图把双向链表中相邻的基本块进行合并,当然这种合并需要满足一定条件,同时要保持程序的原有语义。在合并后,控制流图中的前驱与后继关系也要进行调整。我们需要改动的数据结构有图5.4.1中的双向链表和控制流图。需要

SheIsC的专栏 3754

UCC-UniversalCPPCompiler:通用C ++是标准C ++ 1114的超集,其中增加了“借用”和“ repl”关键字。 “借用”在分配后会自动删除在相同作用域或类中分配的内存。 几乎是垃圾收集器,必须做进一步的工作才能制作“编译时垃圾收集器”。 “ repl”是显式优化的关键字,将一个变量的名称替换为另一个。 这样,该变量可以继续以其他名称使用,从而允许使用干净的代码,了解所发生的情况并保证效率。 (这些都不是特别好,如果进一步发展,可以借用)。 Universal C ++将Unive

UCC-UniversalCPPCompiler:通用C ++是标准C ++ 1114的超集,其中增加了“借用”和“ repl”关键字。 “借用”在分配后会自动删除在相同作用域或类中分配的内存。 几乎是垃圾收集器,必须做进一步的工作才能制作“编译时垃圾收集器”。 “ repl”是显式优化的关键字,将一个变量的名称替换为另一个。 这样,该变量可以继续以其他名称使用,从而允许使用干净的代码,了解所发生的情况并保证效率。 (这些都不是特别好,如果进一步发展,可以借用)。 Universal C ++将Universal C ++代码作为输入和输出ISO Standard C ++代码,并且在ISO Standard C ++的基础上构建。 这样,它是完全独立于平台的,并且是标准的C ++工具:gcc,clang,google native client,msvc可以继续使用

实现一个小型编译程序.zip

1 课设内容 本课程设计任务: 实现一个小型编译程序。 (1) 输入:高级语言源程序; (2) 输出:四元式程序(必做) 汇编语言程序(选做)。 小型编译程序执行分两个阶段: (1) 第一阶段,将高级语言源程序翻译成四元式程序; (2) 第二阶段,将四元式程序翻译成汇编语言目标程序。 本次课程设计要求所有同学完成小型编译程序的第一阶段(必做),第二阶段为选做题目(完成加分)。 2 开发环境 c语言 win10 vs2019 3 参考书籍 《编译教程(第四版)》胡元义 4 SLR(1)分析表 《编译原理教程(第四版)》习题解析与上机指导 链接:https://pan.baidu.com/s/18eCs2iCV-3xpk1JQy_mTXQ 提取码:0gp6 其中,第九章就是课设原题,第十一章就是参考源代码。 希望各位可以在参考书本源代码的基础上自己进行改进,不一定要以我写的这个版本为基准,付费100块,留着买鼠标它不香吗,对吧? 当然,欢迎下载,给孩子一口饭吃,孩子养了猫之后穷得快吃土了

产品经理必看!用Cursor自动生成符合开发规范的技术文档(含UI设计规则模板)

本文详细介绍了产品经理如何利用Cursor工具自动生成符合开发规范的技术文档,并整合UI设计规则模板。通过配置标准化文档结构和设计关联规则,Cursor能有效解决术语不统一、结构混乱等问题,提升跨团队协作效率。文章包含实际案例、规则配置要点及企业级实施方案,帮助产品经理快速掌握AI辅助文档生成技巧。

emacs5lisp的博客 221

STM32F105双路CAN通讯无法进入接收中断问题及解决方法

STM32F105RBT6双路CAN通讯无法进入接收中断问题及解决方法

m0_62383223的博客 3441

【知识图谱】一文看懂知识图谱的搭建实践与科普教程(5万字完结篇)

所有可能的实体对:(“Mate40”,“华为”), (“Mate40”,“手机”), (“华为”,“手机”)。送入关系模型分类,预期输出 (“Mate40”,“华为”): 品牌, (“Mate40”,“手机”): 属于类别, (“华为”,“手机”): 无关系。,定义了图谱中概念和关系的类型层次结构,相当于知识图谱的“纲领”和“schema”。训练完成后,当模型看到新的句子,比如“苹果的MacBook笔记本性能强大”,识别出实体“苹果”(品牌)和“MacBook”(产品)后,就能正确输出关系“品牌”。

weixin_41645791的博客 2611

Zemax非序列模式实战:手把手教你设计光纤耦合圆光斑整形系统(附Thorlabs透镜选型)

本文提供了一份基于Zemax非序列模式的光纤耦合圆光斑整形系统实战设计指南。文章详细讲解了从圆柱体光源建模、Thorlabs商业透镜库选型调用,到系统搭建、光线追迹与优化的完整流程,旨在帮助工程师高效完成从仿真到落地的光束整形系统设计。

weixin_28335283的博客 629

嵌入式Linux网络调试踩坑记:YT8531/YT8521 PHY驱动移植与设备树配置实战

本文深入解析嵌入式Linux系统中YT8531/YT8521 PHY驱动移植与设备树配置的实战经验。从网络不通的常见现象入手,详细介绍了驱动移植关键点、设备树配置详解及常见问题排查技巧,帮助开发者快速解决RGMII接口调试难题,提升嵌入式网络开发效率。

weixin_42525328的博客 444

【通信协议】I2C总线(一主多从)

I2C总线(一主多从)之软件模拟代码详解

m0_75090944的博客 9838

【RT-DETR有效改进】轻量级网络ShuffleNetV2(附代码+修改教程)

从今天开始正式开始更新RT-DETR剑指论文专栏,本专栏的内容会迅速铺开,在短期呢大量更新,价格也会乘阶梯性上涨,所以想要和我一起学习RT-DETR改进,可以在前期直接关注,本文专栏旨在打造全网最好的RT-DETR专栏为想要发论文的家进行服务。RT-DETR剑指论文专栏,持续复现各种顶会内容——论文收割机RT-DETR​​。

Snu77的博客 1993

lammps案例:reaxff势模拟Fe(OH)3高温反应过程

所有的reaxff模拟,如:氧化、腐蚀、热裂解、燃烧等模拟,均可采用此模拟框架,只需要更换data文件、势文件,代码中的control文件可以不写,电荷平衡文件也可以用reaxff替换。该案例主要模拟Fe(OH)3在高温下的反应过程,主要代码来自lammps自带的案例。lammps自带案例没有产物输出,故在此基础上稍加修改,增加了产物输出命令。如果需要系统学习反应势的模拟,可考虑报名培训课程。本文分享一个reaxff反应势的案例。in文件代码已经注释,以供参考。大家好,我是小马老师。

lammps_jiayou的博客 1965

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: C编译器剖析_6.2 汇编代码生成_寄存器的管理
下一篇: C编译器剖析_6.3.2 汇编代码生成_为算术运算产生汇编代码
SheIsC
博客等级 码龄12年 224粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值