C语言的预处理、编译、汇编、链接

一、预处理

预处理指令的执行主要包含下列事情:

1.头文件的包含

2.注释的删除

3.宏定义的替换

4.条件编译的选择

指令:gcc  -E test.c -o test.i    

/* 调用的是预处理器cpp, -E:只进行预处理操作,-o:输出到<文件> , .i表示产生的临时文件 Intermediate */

二、编译

编译之前,C语言编译器会进行词法分析、语法分析(-fsyntax-only)。

在确认所有的指令都符合语法规则之后,将其翻译成相应的后缀为S的汇编文件。

指令:gcc -S test.i -o test.S  

/* 调用的是编译器ccl, -S:编译到汇编语言,不进行汇编和链接, .S:表示汇编文件,注意于.s汇编文件的区别 */


.s :汇编语言源程序;汇编

.S:汇编语言源程序;预处理,汇编

小写的s文件,在后期阶段不在进行预处理操作,所以我们不能在这里面写预处理的语句在里面

大写的S文件,还会进行预处理、汇编等操作,所以我们可以在这里面加入预处理的命  

三、汇编

在编译与汇编之间,编译器通常还会做一些优化操作。

汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程

指令:gcc -c test.S -o test.o

/* 调用的是汇编器as,-c:编译、汇编到目标代码,不进行链接, .o表示产生目标文件, object

此时用file查看test.o文件的类型为ELF 32-bit LSB relocatable类型,这是可重定位的格式 */

四、链接

由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个 源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数等等。所有的这些问题,都需要经链接程序的处理方能得以解决。

链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够诶操作系统装入执行的统一整体。

函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。

指令:gcc test.o -o test

/* 用file查看test文件类型为:ELF 32-bit LSB executable,这是可以被执行的文件格式 */


 

猜你喜欢

转载自my.oschina.net/u/920274/blog/2875477