zoukankan      html  css  js  c++  java
  • 《程序员的自我修养》第二章学习笔记

    第二章 编译和链接

    2.1被隐藏了的过程

    我们知道,一个程序由源代码到可执行文件往往由这几步构成:

    预处理(Prepressing)-> 编译(Compilation)-> 汇编(Assembly)-> 链接(Linking)。

    如图所示,

     

    2.1.1预编译 

    #include<stdio.h>
    
    int main(void)
    {
      printf("Hello World
    ");
      return 0;          
    }

        如上述文件hello.c,  gcc -E hello.c -o hello.i

        预编译过程主要处理哪些源代码文件中的以 "#" 开始的预编译指令,比如 #include,#define 等,主要处理规则如下:

      1. 将所有的#define删除,并且展开所有的宏定义。

      2. 处理所有的预编译指令,比如 "#if" "#ifdef" "#elif" "#else" "#endif"等。

      3. 处理"#include"预编译指令,将被包含的文件插入到该预编译的位置。注意:这个过程是递归进行的,也就是说被包含的文件可能还包含其他文件。

      4. 删除所有的注释 "//"  ''/* */"。

      5. 添加行号和文件名标识,比如#2"hello.c"2,以便于编译时编译器产生调试用的符号信息及用于编译时产生编译错误或警告时能够显示行号

      6. 保留所有的#pragma编译器指令,因为编译器需要用到它们。

      经过预编译后的.i文件不包含任何宏定义(所有的宏都展开了),被包含的文件也被插入到.i文件中。

      参考文献《程序员的自我修养--链接、装载与库》 P39

    2.1.2编译 详情参考2.2

    1,现在版本的GCC把预编译和编译合并成了一个步骤,使用一个叫做ccl的程序来完成这两个步骤。

    2,gcc只是一些后台程序的包装,它会根据不同的参数要求去调用预编译程序ccl,汇编器as,链接器ld。

    2.1.3汇编

    1,汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。

    2,所以汇编器的汇编过程相对于编译器来讲比较简单,它没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译就可以了。

    3,经过预编译、编译和汇编直接输出目标文件(Object File)。

    4,可调用汇编器as来完成,  as hello.s –o hello.o

    5,或者 gcc –c hello.s –o hello.o

    6,也可以一步到位  gcc –c hello.c –o hello.o

    2.1.4链接

    2.2编译器做了什么  参考如下

    http://www.cnblogs.com/xcywt/p/4902789.html

    2.3链接器的年龄比编译器长

    2.4模块拼装---静态链接

      1  人们把每个源代码模块独立编译,然后按照需要将它们“组装”起来,这个组装的过程就是链接(Linking)。

      2  链接的主要内容就是:把各个模块之间相互引用的部分都处理好,使得各个模块之间能够正确的衔接。

      3  从原理上说,链接器的工作无非就是把一些指令对其他符号地址的引用加以修正。

      4  链接过程主要包括了:地址和空间分配(Address and Storage Allocation),符号决议(Symbol Resolution)和重定位(Relocation)。

      5  最基本的静态链接如下图所示,源文件经过编译成目标文件(*.o /  *.obj),目标文件和库一起链接最终形成可执行文件。

     

     

      6  假如main.c用到了另一个模块fun.c中的food()函数。

        (1编译mian.c时并不知道foo()的地址,所以暂时把这些调用foo()的指令的目标地址搁置。

        (2链接器会根据所引用的符号foo,自动去相应的fun.c模块查找foo的地址。

        (3然后将main.c中所有用到foo的指令重新修正,让它们的目标地址为真正的foo函数的地址。

      7  地址修正的过程也叫重定位(Relocation)。

      8  每个要被修正的地方叫一个重定位入口(Relocation Entry)。

    参考文献《程序员的自我修养--链接、装载与库》

  • 相关阅读:
    SpringMVC07处理器方法的返回值
    html01基本标签
    java09数组的使用
    SpringMVC06以对象的方式获取前台的数据
    面向对象的程序设计(五)借用构造函数继承
    面向对象的程序设计(四)原型链继承
    面向对象的程序设计(三)对象字面量创建原型方法与直接创建原型方法的区别
    面向对象的程序设计(二)理解各种方法和属性typeof、instanceof、constructor、prototype、__proto__、isPrototypeOf、hasOwnProperty
    面向对象的程序设计(一)创建对象的各种方法
    二叉树的层次遍历
  • 原文地址:https://www.cnblogs.com/xcywt/p/4951290.html
Copyright © 2011-2022 走看看