编译和链接

目录

Preprocess:

Compile:

Assemble:

Link:


          在linux下,使用gcc来编译程序时,只使用最简单的命令:gcc hello.c(假设源代码文件为hello.c),会得到一个名为 a.out 的可执行文件。其实背后会经过复杂的处理,可分解为4个步骤:预处理(Preprocess)、编译(Compile)、汇编(Assembly)和链接(Link)。构建过程如图:

编译和链接_第1张图片

 


Preprocess:

        预编译过程主要是处理源代码文件中以 “#” 开始的预编译指令

1、将 "#define" 删除,并且展开代码中所有的宏定义

2、处理所有的条件编译指令,"#if"、"#ifdef"、"#elif"…

3、处理 "#include",因为被包含的文件可能还包含其他文件,所以处理这块会比较麻烦

4、删除所有的注释 "//" 和 "/**/"

5、添加行号和文件名标识,以便于产生调试时的行号,编译错误或警告的行号

6、保留所有的 "#pragma" 编译器指令,因为编译器需要使用到

eg:

gcc -E hellc.c -o hello.i or gcc -E hello.c > hello.i

关于“-E”选项的解释: Preprocess only; do not compile, assemble or link.


Compile:

编译过程就是把预处理完的文件进行一系列复杂的词法分析、语法分析、语义分析及优化后产生相应的汇编代码文件。

eg:

 gcc -S hello.i -o hello.s

关于 “-S” 选项的解释:Compile only; do not assemble or link.


Assemble:

汇编是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。只是根据汇编指令和机器指令的对照表一一进行翻译。

可以调用汇编器工具"as"来完成汇编

eg:

as hello.s -o hello.o

也可以使用gcc命令从C源代码文件开始,经过Preprocess,Compile和assemble后直接输出object(目标)文件

eg:

gcc -c hello.c -o  hello.o

关于“-C”选项的解释:Compile and assemble, but do not link.


Link:

        链接可分为静态链接和动态链接,目的是将各种object文件链接起来得到可执行文件。链接的过程是非常复杂的,简单点来说,链接的主要内容就是把各个模块之间相互引用的部分都处理好,使得各个模块之间能正常的工作。

举个例子:

        在a.c中我用到了一个函数function{},这个函数是定义在b.c中的。在各自生成object文件的时候,a.o中是不知道functionn{}函数的地址的,这个阶段是将其处理为0的。当使用链接器ld执行链接过程的时候,进行符号的解析与重定位后,确定了function{}函数的地址。然后就可以把跳转到function{}函数的那条指令所要跳转的地址换为真实的function{}的地址,这个过程就是链接。

你可能感兴趣的:(嵌入式-Embedded,编译和链接,可执行文件的由来,从C到可执行文件)