C程序的编译与链接

时间:2023-03-08 18:11:47
C程序的编译与链接

编译器驱动程序

编译器驱动程序可以在用户需要时调用语言预处理器、编译器、汇编器和链接器。

例如使用GNU编译系统,我们需要使用如下命令来调用GCC驱动程序:

gcc -o main main.c

编译过程

一个C语言程序从源文件到可执行文件经过如下步骤:

  1. 驱动程序运行C预处理器(cpp),它将main.c翻译成一个ASCII码的中间文件main.i。预处理指令以#开头标识。
gcc -E -o main.i main.c

在预处理阶段进行的工作包括:

* 文件包含

* 宏替换

* 条件编译指令

* 其他预处理指令

  1. 接下来,驱动程序运行C编译器(cc1)它将main.i翻译成一个ASCII汇编语言文件main.s
gcc -S -o main.s main.i
  1. 然后,驱动程序运行汇编器(as),它将main.s翻译成一个可重定位目标文件main.o
gcc -c -o main.o main.s
  1. 最后,驱动程序运行链接程序(ld),将经前面步骤生成的多个可重定位目标文件以及一些系统必要的系统目标文件组合起来,创建一个可执行目标文件。
gcc -o main main.o

(这里均使用gcc指令完成,使用单独的程序例如ld则需要自己手动链接大量系统目标文件)

静态链接

像unix ld程序这样的静态链接器以一组可重定位目标文件命令行参数作为输入,生成一个完全链接的可以加载和运行的可执行目标文件作为输出。

输入的可重定位目标文件由各种不同的代码和数据节组成。

链接器的两个主要任务:

  1. 符号解析

    目的是将每个符号引用刚好和一个符号定义联系起来。
  2. 重定位

    编译器和汇编器生成地址从0开始的代码和数据节。链接器通过把每个符号定义与存储器位置联系起来,然后修改所有对这些符号的引用,使得它们指向这个存储器位置,从而重定位这些节