手把手带你写一门编程语言
宫文学
北京原点代码 CEO
7534 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
起步篇:让一门超简单的语言跑起来 (21讲)
结束语 (1讲)
手把手带你写一门编程语言
15
15
1.0x
00:00/00:00
登录|注册

18|生成本地代码第3关:实现完整的功能

你好,我是宫文学。
到目前为止,我们已经把挑战生成本地代码的过程中会遇到的各种难点都解决了,也就是说,我们已经实现基本的寄存器分配算法,并维护好了栈桢。在这个基础上,我们只需要再实现其他的语法特性就行了。
所以,在今天这节课,我们要让编译器支持条件语句和循环语句。这样的话,我们就可以为前面一直在使用的一些例子,比如生成斐波那契数列的程序,生成本地代码了。然后,我们可以再比较一次不同运行时机制下的性能表现。
还记得吗?我们在前面已经分别使用了 AST 解释器、基于 JavaScript 的虚拟机和基于 C 语言的虚拟机来生成斐波那契数列。现在我们就看看用我们自己生成的本地代码,性能上是否会有巨大的变化。
在这个过程中,我们还会再次认识 CFG 这种数据结构,也会考察一下如何支持一元运算,让我们的语言特性更加丰富。
那首先我们来看一下,如何实现 if 语句和 for 循环语句。

支持 if 语句和 for 循环语句

在前面的课程中,我们曾经练习过为 if 语句和 for 循环语句生成字节码。不知道你还记不记得,其中的难点就是生成跳转指令。在今天这节课,我们会完成类似的任务,但采用的是一个稍微不同的方法。
我们还是先来研究一下 if 语句,看看针对 if 语句,编译器需要生成什么代码。我们采用下面一个 C 语言的示例程序,更详细的代码你可以参见代码库中的if.c
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

编译器生成本地代码的关键步骤和技术要点是本文的重点。文章首先回顾了前几节课程中解决的难点,并指出在基本的寄存器分配算法和栈桢维护的基础上,只需实现其他语法特性即可生成本地代码。作者详细讲解了为if语句和for循环语句生成本地代码的过程,包括汇编代码中的跳转指令的生成逻辑和一元运算的特殊实现方式。此外,文章还提到了CFG(控制流图)这种数据结构,并指出在学习寄存器分配算法时会涉及到与CFG相关的内容。在性能比拼方面,本地代码版的速度是栈机版的20多倍,性能有了极大的提升。最后,文章提到下节课将升级寄存器分配算法,继续提升程序的性能。整体而言,本文深入介绍了编译器生成本地代码的关键步骤和技术要点,对于想要深入了解编译器工作原理的读者具有重要参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你写一门编程语言》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • qinsi
    文中的CFG都是连通的。如果有不连通的部分就是死代码,可以不用生成。
    2021-09-20
    2
  • 有学识的兔子
    CFG control-flow graph,每个节点都对应着一个基本块(一系列顺序执行的指令),通过带箭头的线将基本块之间的关系构建起来,形成一张图。从if和for语句来看,它们都是由多个基本块构成的,通过构建CFG,将基本块进行编号并通过条件跳转,实现了一个基本块跳转到到另一个基本块,不会出现不可达的基本块。通过CFG,构建了基本块和它们的跳转关系,基于这两者生成汇编代码貌似变得简单。
    2021-09-21
    1
  • 奋斗的蜗牛
    老师讲得太棒了~,要拼接多个条件表达式,我想可以将每个表达式转成1或者0来运算
    2021-09-20
    1
  • ifelse
    学习打卡
    2022-09-19归属地:浙江
  • ...
    生成本地代码的使用场景是JIT? 如果完全使用本地代码的话 应该不需要虚拟机了
    2021-11-02
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部