编译原理基础

语言类型

低级语言通常指更接近计算机硬件、对机器依赖更强、抽象程度更低的编程语言。主要有两类:

机器语言:由二进制指令组成,CPU 可以直接执行,但人很难读写。

汇编语言:用助记符(如 MOV、ADD)表示机器指令,和具体 CPU 架构强相关,仍需汇编器翻译成机器码。

所以“低级”不是“差”的意思,而是抽象层级低:低级语言更贴近硬件,控制精细、效率高,但可移植性和开发效率通常不如 C 这类高级语言。C 语言常被称为“中级语言”,因为它既有高级语言的结构化特性,又能较直接地操作内存和硬件。

编译程序是一种翻译程序,把源程序高级语言写的源程序,翻译成等价的用低级语言写的目标程序。

汇编程序->机器语言

编译程序把汇编语言翻译成机器语言。编译程序把高级语言翻译成低级语言,解释程序边翻译边执行,不生成目标程序。

编译类似整本书一次性读完,以后直接读译本。解释类似同声传译,说一句翻译一句。

编译分为五个阶段。

  1. 词法分析
  2. 语法分析
  3. 中间代码生成
  4. 代码优化
  5. 目标代码生成

其中表格管理和出错处理贯穿全过程。

阶段

词法分析

以position:=initial+rate*60为例

分别是标识符,赋值号,标识符,加号,标识符,乘号,整数。标识符会登记到符号表中。

image.png

语法分析

语法分析根据语法规则,把单词组合成表达式、语句这样的语法单位。构造语法树,乘法优先级高。所以rate*60先组成一颗子树,再和initial相加。最后赋值给position。

image.png

语义分析

语义分析,检查静态语义,手机类型信息。

浮点型就是实型,real。“浮点型”告诉你它怎么存,“实型”告诉你它是用来干嘛的。 两者说的是同一件事,只是视角不同。

这里还涉及到自动转换问题,加入id1,id2,id3是real,60是int。那就要插入一个类型转换inttoreal。然后生成中间代码。

三地址代码(Three-address code)简称TAC或3AC,是编译原理中重要的中间表示IR。

三地址代码的三地址指的,每条指令最多包含三个操作数(地址):俩个源操作和一个目标操作数。其一般形式为

x=y op z

x:目标地址,结果存放位置

y,z:源操作数,变量、常量或临时变量

op:运算符(算术、逻辑、比较)等

每条指令通常只做一件事,且结果总是赋值给一个变量或者临时变量。

image.png

代码优化

代码优化对中间代码做等价变换。让程序更快更省。60是常数类型转换可以在编译时完成。t3只是中转也可以省掉。

image.png

目标代码生成

目标代码生成把中间代码翻译成具体机器的指令。核心是选择指令和分配寄存器。

比如取id3到寄存器R2,乘以60,取id2到R1,加上R2,最后把R1存回id1

image.png

前端后端

编译程序通常分为前端和后端.

前端与源语言优化与目标机器无关。包括词法分析语法分析,语义分析,中间代码生成。以及与机器无关的优化。

后端与目标机器有关,包括与机器优化的优化,目标代码生成。

中间代码就是俩者之间的接口。

image.png

其中LLVM是统一的但IR(图片中的模型)统一且独立。LLVM的IR是一个语言无关、目标无关的中间表示,具有类似RISC的三地址码和SSA(静态单赋值)形式。它的设计目标就是让前端Clang。所有的优化都在这同一套IR上允许。。

GCC中采用了多层、逐级下降的IR体系。GCC的后端代码生成,与架构目标紧密相关。GCC的IR层级更多,内部耦合更紧。没有像LLVM那样清晰稳定的契约来分离前后端。GCC的RTL与后端绑定得很深,且随着后端发生变化。

遍也较躺,是指对于源程序或者它的中间形式,从头到尾扫描一遍,并完成规定任务的过程。

一遍可以完成几个阶段,一个阶段也可以分成几遍。遍数少,编译快,遍数多,结构清晰。

gcc -E只做预处理,展开include。把宏RATE替换为60。

gcc -S把它编译成汇编文件pos.s。

gcc -c汇编成目标文件pos.o

最后链接成可执行文件。

image.png

加上gcc -v选项可以感到gcc在背后调用了三个程序。cc1是真正的编译器,as是汇编器,collect2是链接器。GCC本身只是一个驱动程序。不同的错误由不同的阶段发现。

编译程序本身常用T型图表示

左边是源语言,右边是目标语言,底下是编写它的语言。自编译又叫自举。

先用别的语言实现语言L的一个小核心,再用L自己写出完整的L编译器。

GCC就是用C和C++写的。

image.png

交叉编译:在一种机器上生成另一种机器的目标代码。比如在电脑上编译手机或者单片机的程序。

移植:把一台机器上的编译程序搬到另一台机器上。

Last modification:November 12, 2026
如果觉得我的文章对你有用,请随意赞赏