• 编译和链接


    目录

    Preprocess:

    Compile:

    Assemble:

    Link:


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

     


    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{}的地址,这个过程就是链接。

  • 相关阅读:
    【学习笔记】Prufer序列
    不讲故事的设计模式-责任链模式
    MySQL学习笔记27
    Spring 依赖注入和循环依赖
    ABCD四个顺序执行方法,拓展性延申
    211. 添加与搜索单词 - 数据结构设计
    基于路网层次收缩的快速分布式地图匹配算法
    CLIP:连接文本-图像
    19爬虫之常见反反扒措施
    【翻译】Image Style Transfer Using Convolutional Neural Networks
  • 原文地址:https://blog.csdn.net/qq_41867145/article/details/125538844