【Linux】预编译,编译,汇编,链接的四过程

第一个阶段是预编译阶段,在正式的编译阶段之前进行。预处编译段将根据已放置在文件中的预处理指令来修改源文件的内容。如#include指令就是一个预处理指令,它把头文件的内容添加到.cpp文件中。宏替换也是在预编译阶段完成的。在预编译完成后,也即.i文件中,所有以#开头的语句都不存在,已经被替换了。

第二个阶段编译、优化阶段,将其翻译成等价的中间代码表示或汇编代码,并执行优化。

第三个阶段是汇编,把汇编语言代码翻译成目标机器指令

第四个阶段是链接。合并符号表 合并section 调整段大小和段起始位置

                                符号重定位

【Linux】预编译,编译,汇编,链接的四过程

gcc main.c编译文件,会产生一个a.out的可执行程序,然后./a.out运行该程序。

将这个操作分解开来看:

1.预编译:gcc main.c -E -o main.i

表示让 gcc 只进行 “预编译” 就行了。 所谓的预编译,就是把程序中的宏展开, 把头文件的内容展开包含进来等等一些编译前的预处理操作,然后-o保存在test.i里。

2.编译:gcc main.i -S -o main.s

表示让 gcc 只进行“预编译编译”就行了。将main.i翻译成文本文件main.s,它包含一个汇编语言程序。编译会从词法、语法和语义上对文件进行分析, 并进行汇编代码生成, 形成的还是文本文件------汇编语言文件。以.s作为文件扩展名,然后-o保存在main.s里。

3.汇编:gcc main.s -c -o main.o

表示让gcc只进行“预编译编译汇编”就行了。汇编器将main.s翻译成二进制机器语言指令,所以我们就看不懂了,把这些指令打包成一种叫做可重定位目标程序格式,并保存在.o文件中。

4.链接:gcc main.o -o a.out

表示让gcc只进行“预处理编译汇编链接”。最后将二进制机器语言指令转换成二进制的可执行程序。

【Linux】预编译,编译,汇编,链接的四过程
编译:gcc -c main.c    --->     main.o
链接:gcc main.o -o main     --->    main
一步生成可执行文件:gcc main.c -o main    --->main