• 编译过程(从编译到链接)


    当我们写完代码编译的时候,计算机都进行了哪些步骤呢?这些步骤又都有些什么作用呢?

    一、执行一个程序的过程

    当我们编写一个程序并编译执行,如下(hello.c)

    #include <stdio.h>
    int main()
    {
        printf("Hello World
    ");
        return 0;
    }
    /*编译执行*/ $gcc hello.c
    -o hello.out $./hello.out Hello World

    那么在其中执行了如图的过程:

    其中的主要过程包括:

    预处理(Propressing):处理"#define、#include、#if……"等,删除注释,添加行号,但保留所有#pragma编译器指令;

    编译(Compilation):词法分析、语法分析、语义分析及优化后产生汇编代码文件;

    汇编(Assembly):将汇编代码转换成机器可以执行的指令;

    链接(Linking):将所有需要的静态、动态库、文件等链接成为可执行程序。

    二、编译过程

     也就是上图中的编译部分,主要过程共分为6步,如下图:

    扫描(Scanner):用类似于有限状态机,把代码分割成一系列记号(Token);

    语法分析(Parser):通过对记号进行分析,生成语法树(Syntax Tree);

    语义分析(Semantic Analyzer):完成表达式语法层面的分析,并不关心意义;如不会处理两个指针相乘;

    源代码优化(Source Code Optimizer):将语法树转换成中间代码,如三地址码 x = y op z;

    代码生成(Code generator): 初步生成目标代码;

    目标代码优化(Code Optimizer):将目标代码优化为最终的代码。比如选择合适的寻址方式、使用位移来代替乘法运算、删除多余指令等。

    三、在各个步骤中使用的编译命令

    用下面的程序举例子

    #include<stdio.h>
    #define MAX 100
    int main()
    {
    /*I am only the test*/
    printf("Hello World!");
    printf("%d
    ",MAX);
    return 0;
    }

    gcc -E hello.c -o hello.i //后可以看到宏定义和注释都没有了

    gcc -S hello.i -o hello.s //后可以看到被编译成的汇编文件。

    gcc -c hello.s -o hello.o //将汇编文件生成目标文件

    以上三个步骤可以用一句话代替: gcc -c hello.c -o hello.o 这样可以直接生成目标文件。

    最后链接成可执行文件有点麻烦:
    ld -static /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.1.3/crtbeginT.o -L/usr/lib/gcc/i486-linux-gnu/4.1.3 -L/usr/lib -L/lib hello.o --start-group -lgcc -lgcc_eh -lc --end-group /usr/lib/gcc/i486-linux-gnu/4.1.3/crtend.o /usr/lib/crtn.o

    当然各个文件在不同系统中的路径也不一定相同,如我在centos6.6就是下面的结果:
    ld -static /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtbeginT.o -L/usr/lib/gcc/x86_64-redhat-linux/4.4.4 -L/usr/lib64 -L/lib64 hello.o --start-group -lgcc -lgcc_eh -lc --end-group /usr/lib/gcc/x86_64-redhat-linux/4.4.4/crtend.o /usr/lib64/crtn.o

  • 相关阅读:
    Educational Codeforces Round 6
    Codeforces Round #373 (Div. 2)
    尺取法
    Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2)
    逆元(数论倒数)
    最大公约数gcd,最小公倍数lcm,扩展欧几里得
    hdu 6395 Sequence (分段矩阵快速幂)
    快速幂
    hdu 6432 Cyclic
    hdu 6397 charactor encoding
  • 原文地址:https://www.cnblogs.com/bugutian/p/5087577.html
Copyright © 2020-2023  润新知