程序编译的四个过程

引言

hollo.c是大部分程序员写的第一个程序,本篇博客将介绍编译运行hello.c,操作系统将做的事情。

编译系统

hello.c是一个高级C语言代码,格式如下

#include 
int main()
{
printf("hello world\n");

return 0;
}

在系统中运行该程序,则必须把每一条C语言代码转化成低级机器语言指令,这些指令按照可执行目标文件的格式排列好,并在磁盘上以二进制文件的形式储存起来,形成可执行目标文件。
在我们使用的例如visual studio和devc++等软件,替程序员做好了这一切,如果我们使用gcc编译器可以逐步的看到,程序的变化。
程序编译的四个过程_第1张图片
在这里GCC驱动文件读取hello.c,并生成了可执行文件hello,这其中可以分为四个步骤,预处理,编译,汇编,链接,看起来比较乱,我们下面分别对其说明

预处理

命令:gcc -E hello.c -o hello.i
预处理是读取c源程序,对其中的伪指令(以#开头的指令,也就是宏)和特殊符号进行“替代”处理;经过此处理,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,仍然是C文件。但内容有所不同。

伪指令主要包括以下三个方面:

(1)宏定义指令,如#define Name TokenString,#undef以及编译器内建的一些宏,如__DATE__, FILE, LINE, TIME, FUNCTION 等。

(2)条件编译指令,如#ifdef,#ifndef,#else,#elif,#endif等。
(3) 头文件包含指令,如#include "FileName"或者#include 等。

执行指令得到hello.i,打开后如下
程序编译的四个过程_第2张图片
将#include替换为了800多行的代码,并且去掉了注释,需要注意的一点是,在预处理阶段,并不会检查语法错误。

编译

命令:gcc -S hello.i -o hello.o
编译时,编译器将文本文件hello.i转化为了文本文件hello.s

这个阶段编译器主要做词法分析、语法分析、语义分析等,在检查无错误后后,把代码翻译成汇编语言[2]。可用gcc的参数-S来参看。
编译器(ccl)将文本文件hello.i 翻译成文本文件hello.s, 它包含一个汇编语言程序。 这是非常有用的,它为不同的高级语言的不同的编译器提供了相同的输出文件格式。
打开hello.s
程序编译的四个过程_第3张图片

汇编

命令:gcc -c hello.s -o hello.o

汇编器将hello.s翻译成机器语言指令,再将这些指令按照可重定向目标程序的格式储存,结果保存在hello.o二进制文件当中,如果我们打开hello.o会查看到一堆乱码,如下。
程序编译的四个过程_第4张图片

链接

printf函数存在于一个名为printf.o的单独预编译目标文件中。必须得将其并入到hello.o的程序中,链接器就是负责处理这两个的并入,结果得到hello文件,它就是一个可执行的目标文件

兰德尔E.布莱恩特:深入了解计算机操作系统(第三版):机械工业出版社,2015.

你可能感兴趣的:(个人理解)