您的位置:首页 > 编程语言 > C语言/C++

c程序的编译和链接过程

2016-11-03 11:23 176 查看
编译过程:
              预编译

  编译
 汇编
 链接
可执行文件格式: Windows : PE (portable executable)
                              Linux : ELF (executable linkable format)
                             均来自于COFF (Common file format)
编译和链接的整个过程:
(1)预处理(宏替换,删除注释和多余的空白字符,条件编译,文件包含) 
(2)编译(gcc检查代码规范性,是否有语法错误,生成汇编) 
(3)汇编(生成机器可识别代码,将编译生成的.s文件转成.o二进制目标代码) 
(4)链接(生成可执行文件或库文件)

编译和链接图解分析:






编译过程:驱动程序首先运行C预处理器(cpp),它将C的源程序main.c翻译成一个ASCII码的中间文件main.i.接下来,驱动程序运行C编译器(ccl),将main.i翻译成一个ASCII汇编语言文件main.s.然后,驱动程序运行汇编器(as),它将main.s翻译成一个可重定位的目标文件main.o.

在成功编译后,就进入了链接的阶段
链接过程:链接是把目标代码,用到的库文件以及操作系统用到的其他目标代码通过链接器进行组   织最终形成一个可执行程序。
                  链接就是将不同部分的代码和数据收集和组合成为一个单一文件的过程,这个文件可被加载或拷贝到存储器执行,链接可以执行与编译时(源代码被翻译成机器代码时),也可以执行与加载时(在程序被加载器加载到存储器并执行时),甚至执行与运行时,由应用程序来执行.在现代系统中,链接是由链接器自动执行的.

 
链接器分为:静态链接器和动态链接器两种.

(1)静态链接器
  静态链接器以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的可以加载和运行的可执行目标文件作为输出.
  静态链接器主要完成两个任务:

  1>符号解析:目标文件定义和引用符号.符号解析的目的在于将每个符号引用和一个符号定义联系起来.
  2>重定位:编译器和汇编器生成从地址零开始的代码和数据节.链接器通过把每个符号定义和一个存储器位置联系起来,然后修改所有对这些符号的引用,使得他们执行这个存储位置,从而重定位这些节.

(2)动态链接器
  共享库是一个目标模块,在运行时,可以加载到任意的存储器地址,并在存储器中和一个程序链接起来.这个过程称为动态链接,是由动态链接器完成的.
  共享库的共享在两个方面有所不同.首先,在任何给定的文件系统中,对于一个库只有一个.so文件.所有引用该库德可执行目标文件共享这个.so文件中的代码和数据,而不是像静态库德内容那样被拷贝和嵌入到引用它们的可执行的文件中.其次,在存储器中,一个共享库的.text节只有一个副本可以被不同的正在运行的进程共享.
动态链接 :
 启动动态链接器本身
 加载需要的共享对象
 重定位和初始化

这里涉及到一个重要的概念:函数库查看上面的小程序会发现里面并没有定义printf函数的实现,并且在预编译阶段包含进去的“stdio.h”里面也只有它的声明,而没有定义函数的实现。那么printf实在哪里实现的呢? 
其实系统把对这些函数的实现都做到名字为libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的路径“/user/lib”下面进行查找,并且链接到lib.so.6库函数中去,这样就能实现printf函数了,这也就是链接的作用。 
函数库分为两种:静态库和动态库。静态库是指在编译链接时将库文件的代码全部加入到可执行文件里,因此生成的文件比较大,但在执行过程中就不会再用到库文件了,后缀名一般为.a;动态库和它相反,在编译链接过程中并没有将库文件加入到可执行文件里面去,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销,后缀名一般为.so。上面提到的libc.so.6就是动态库,所以也就可以得到gcc在编译时默认使用动态库。完成链接过程,gcc就可以生成可执行文件main了。 

预处理器:将.c 文件转化成 .i文件,使用的gcc命令是:gcc –E,对应于预处理命令cpp;
编译器:将.c/.h文件转换成.s文件,使用的gcc命令是:gcc –S,对应于编译命令 cc –S;
汇编器:将.s 文件转化成 .o文件,使用的gcc 命令是:gcc –c,对应于汇编命令是 as;
链接器:将.o文件转化成可执行程序,使用的gcc 命令是: gcc,对应于链接命令是 ld;
加载器:将可执行程序加载到内存并进行执行,loader和ld-linux.so。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 编译和链接