编译的幕后花絮
为了理解编译器怎么把多个源文件编译成一个程序,需要拉开帷幕,看看编译器到底怎么工作。
- 预处理:修改代码。
- 编译:转换成汇编代码。
C语言看似底层,但计算机还是无法理解它。计算机只理解更低层的机器代码指令。而生成机器代码的第一步就是把C语言源代码转化为汇编语言代码,看起来像这样:
movq -24(%rbp), %rax
movzbl (%rax), %eax
movl %eax, %edx
是不是很难懂?汇编语言描述了程序运行时中央处理器需要执行的指令。C编译器有很多食谱,覆盖了C语言的方方面面,比如如何把if
语句或函数调用转化为一串汇编语言指令。但汇编语言还不够底层,所以我们需要……
- 汇编:生成目标代码。
编译器需要将这些符号代码汇编成机器代码或目标代码,即CPU内部电路执行的二进制代码。
你已经把C语言源代码转化成电路所需的0和1了。还差最后一步,你给了编译器几个文件来编译程序,编译器会为每个源文件生成一个目标代码,为了生成可执行程序,还需要对这些目标文件做一件事……
- 链接:放在一起。
一旦有了全部的目标代码,就需要像拼“七巧板”那样把它们拼在一起,构成可执行程序。当某个目标代码的代码调用了另一个目标代码的函数时,编译器会把它们连接在一起。同时,链接还会确保程序能够调用库代码。最后,程序会写到一个可执行程序文件中,文件格式视操作系统而定,操作系统会根据文件格式把程序加载到存储器中运行。
怎么让gcc知道我们想用几个单独的源文件生成可执行程序呢?