C代码编译过程
过程简介
以hello.c 代码为例,当我们编译hello.c 时。
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
一般使用的编译命令是
gcc -o hello hello.c
我们能看到通过该命令后会得到一个可执行文件hello ,执行该程序
./hello
我们会在界面上看到
hello world
一般而言我们不需要追究编译的细节,就好比我们去餐厅吃饭,我们不需要去细问厨师是先放盐还是先放油。但如果我们有志于成为一个合格的厨师的话,那么这些做菜的细节就很重要,事实上从hello.c 变成hello 也是有很多过程的,分别是预处理,将头文件放入hello.c 中,将宏定义进行替换,将注释去掉等,得到hello.i 文件。接着是编译,将hello.i 文件由代码变成汇编语言,得到hello.s ,再接着是汇编阶段,将hello.s 翻译成机器语言指令hello.o 。最后是链接阶段,将调用的函数合并到hello.o 中,比如再hello.c 中我们调用了printf 函数,这个函数的预编译好的文件printf.o 就是在这个阶段与hello.o 进行合并生成我们最终的可执行文件hello
预处理
预处理阶段,预处理器cpp 根据以字符# 开头的命令对原始的代码进行处理。以上文的hello.c 为例,在这个环节,预处理器cpp 会根据第一行的命令#include <stdio.h> 将stdio.h 文件中的所有内容插入到hello.c 中。我们可以使用gcc 命令来对这个环节进行观察。
gcc -E hello.c -o hello.i
我们使用vim 打开hello.i 文件,我们会发现多了700多行代码,在文件的最后我们找到了自己写的代码。
编译
编译阶段,编译器ccl 将C语言代码hello.i 翻译为汇编语言hello.s ,我们使用gcc 命令观察这个环节
gcc -S hello.i -o hello.s
使用cat 或者vim 打开hello.s 文件,其内容如图所示
汇编
汇编阶段,这个阶段将汇编语言翻译为机器语言也就是01 ,hello.s 也将变成二进制文件hello.o ,我们使用gcc 命令定位到这个阶段。
gcc -C hello.s -o hello.o
我们用vim 打开test.o 只能看到乱码,使用xxd 让hello.o 以16进制的形式展现出来。
链接
链接阶段将其他已经预编译好的.o 文件链接整合到一起,比如过程简介环节提到过的printf.o 文件,我们使用gcc 命令进行定位
gcc hello.c -o hello
使用xxd 让hello 以16进制的形式展现出来。
|