Mslxl

Integrate Life

编译原理:绪论

Posted at # Compiler

最近在学习编译原理,把笔记整理一下写在上面


什么是编译?

编译是将一种语言翻译为另外一种语言,将被翻译的语言叫做源程序,而翻译之后的语言叫做目标语言一般来说,编译是将高级语言翻译为低级语言,例如 GCC 等 C++ 编译器就是将 C++ 翻译为机器语言或中间语言。

高级语言(High Level Language)符合人的表达习惯且易于学习和记忆,常见的就是 C++ 、Java。

低级语言则相反,并且与运行的机器密切相关,比如汇编语言(Assembly Language)和机器语言(Machine Language)。

下面分别是 C++ 、汇编语言和机器语言的画风:

x = 1
MOV X,2
C706 0000 0002

通过上面几个例子,我们就知道了什么是编译以及为什么要编译。

编译器在语言处理中的位置

在变异中,除了编译器,我们还需要其他的一些东西。

首先,我们需要预处理器 (Preprocessor),源程序可能会被分割成模块,储存在不同的文件中,预处理器则会把他们 聚合 在一起,并把其中称之为宏的缩写语句展开。

之后,被处理过的源程序则会通过 编译器汇编器(Assembler) 生成可重定位 (Relocatable) 的机器代码,可重定位代码在内存中存放的起始位置 L 是不固定的,代码中的所有地址都是相对于这个 L 的相对地址,起始地址+相对地址=绝对地址起始地址 + 相对地址 = 绝对地址,因为代码中的内存地址都是相对的,所以,我们需要加载器 (Loader) 来修改可重定位地址,将修改后的指令和数据放在内存中适当的位置,还有一种情况使用的是 链接器 (Linker) 而不是加载器,因为大型程序会被分割成很多部分,在这种情况下,链接器会将生成可重定位的机器代码与库文件进行链接,从而生成可执行代码,同时链接器还会解决外部内存地址问题,所谓外部内存地址,就是指一个文件中的代码,可能会引用另一个文件中的对象或者过程,这些被引用的对象或者过程的地址,相对于这个文件来说就是外部地址

一个完整的系统大致就是这样

graph TD
	Start-- 源程序 -->预处理器
	预处理器-- 经过处理的源程序 -->编译器
	编译器-- 汇编语言程序 -->汇编器
	汇编器-- 可重定位的机器代码 -->链接器/加载器
	链接器/加载器-- 目标机器代码 -->Fin
moe-counter

统计自 2024 年 9 月