编译链接之原理

  • 内容
  • 相关

  对于源文件是怎么变成可执行程序的,当执行一个程序时,都做了那些处理,相信大家都比较好奇。在这里将简单介绍下程序的编译链接原理。

  在ANSI C的任何一种实现中,存在两种环境翻译环境和执行环境。翻译环境主要将源代码转化为可执行的机器指令。执行环境用于实际执行代码。在翻译环境中,主要进行编译和链接,一个程序在编译阶段主要进行了预处理、编译和汇编处理。下面将对各阶段进行分析。(环境为centos6.5)

 翻译环境  

    预处理 

        命令:gcc -E Main.c -o Main.i


 预处理阶段的主要作用:(文本操作,产生 *.o文件)

        a. 头文件的包含(处理#include预编译指令,将被包含的文件插入到预编译处理指令的位置)

     b. 注释的删除

     c. #define标识符的删除和替换

     e. 宏替换

     d.添加行号和文本标识,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能欧够显示行号 

     f. 保留所用的#program编译器指令,因为编译器需要使用它们

  编译   

        命令:gcc -S Main.c -o Main.s

 编译阶段的主要作用:(生成汇编代码)

        语法分析、词法分析、语义分析、符号汇总


  汇编

     命令:gcc -c test.c

 汇编阶段的主要作用:生成test.o目标文件 由汇编指令---> 二进制指令

             形成符号表(将编译阶段汇总的符号形成一张符号表)

        可以使用readelf -s test.o查看符号表

 链接

      每个源代码模块独立地编译,然后按照要求将他们组装起来,这个组装过程就是链接。链接的主要内容就是把各个模块之间的相互引用部分处理好,使得各个模块之间能够正确的链接。

    主要作用:

        a.符号表的合并和符号表的重定位  

        将汇编阶段生成的符号表进行合并。可重定位目标文件之中用来存放变量和其入口地址的符号表,重定位是指在链接阶段连接器会查找符号表,当发现某个符号表存在没有决议的内存地址时,连接器就会查找所有符号表,一直发现这些这些尚未决议的符号变量的内存地址写进符号表。直达所有的符号变量都能够找到合法的内存地址时,链接阶段重定位完成。否则会出现链接错误。

        b.段表的合并

         在汇编阶段生成的Main.o为elf格式的文件,里面包含段表等信息,合并段表是将每个可执行文件中对应的各段信息进行合并。

 运行环境           


    程序的执行环境:

           1. 程序必须载入内存。 在有操作系统的环境中,一般由操作系统完成。

           2. 程序的执行开始。接着便调用main函数

           3. 开始执行程序代码,这个时候程序将使用一个运行时堆栈,存储函数的局部变量和返回地址。程序也可以使用静态内容,存储以静态内存中的变量在程序的整个执行过程一直保留他们的值。

           4. 终止程序。 正常终止main函数,也有可能是意外终止。


        这里只是对编译和链接过程做了简单的介绍,以至于我们可以对源程序到可执行程序的过程有一个基本的认识。


本文标签:这篇文章木有标签

版权声明:若无特殊注明,本文皆为《晶天》原创,转载请保留文章出处。

本文链接:编译链接之原理 - https://www.jqlab.cn/post-455.html