什么是编译器,链接器,加载器?

Sac*_*hin 104 compiler-construction linker terminology loader

我想深入了解编译器,链接器和加载器的意义和工作.参考任何语言,最好是c ++.

小智 173

=====> COMPILATION PROCESS <======

                     |
                     |---->  Input is Source file(.c)
                     |
                     V
            +=================+
            |                 |
            | C Preprocessor  |
            |                 |
            +=================+
                     |
                     | ---> Pure C file ( comd:cc -E <file.name> )
                     |
                     V
            +=================+
            |                 |
            | Lexical Analyzer|
            |                 |
            +-----------------+
            |                 |
            | Syntax Analyzer |
            |                 |
            +-----------------+
            |                 |
            | Semantic Analyze|
            |                 |
            +-----------------+
            |                 |
            | Pre Optimization|
            |                 |
            +-----------------+
            |                 |
            | Code generation |
            |                 |
            +-----------------+
            |                 |
            | Post Optimize   |
            |                 |
            +=================+
                     |
                     |--->  Assembly code (comd: cc -S <file.name> )
                     |
                     V
            +=================+
            |                 |
            |   Assembler     |
            |                 |
            +=================+
                     |
                     |--->  Object file (.obj) (comd: cc -c <file.name>)
                     |
                     V
            +=================+
            |     Linker      |
            |      and        |
            |     loader      |
            +=================+
                     |
                     |--->  Executable (.Exe/a.out) (com:cc <file.name> ) 
                     |
                     V
            Executable file(a.out)
Run Code Online (Sandbox Code Playgroud)

C预处理器: -

C预处理是编译的第一步.它处理:

  1. #define 声明.
  2. #include 声明.
  3. 有条件的陈述.

该单元的目的是将C源文件转换为Pure C代码文件.

C编译:

该单元有六个步骤:

1)词法分析器:

它结合了源文件中的字符,形成"TOKEN".令牌是一组没有'space','tab'和'new line'的字符.因此,这个编译单元也称为"TOKENIZER".它还会删除注释,生成符号表和重定位表条目.

2)句法分析器:

此单元检查代码中的语法.例如:

{
    int a;
    int b;
    int c;
    int d;

    d = a + b - c *   ;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将生成解析错误,因为方程式不平衡.本单元通过生成解析器树在内部对此进行检查,如下所示:

                            =
                          /   \
                        d       -
                              /     \
                            +           *
                          /   \       /   \
                        a       b   c       ?
Run Code Online (Sandbox Code Playgroud)

因此该单元也称为PARSER.

3)语义分析器:

本单元检查语句中的含义.例如:

{
    int i;
    int *p;

    p = i;
    -----
    -----
    -----
}
Run Code Online (Sandbox Code Playgroud)

上面的代码生成错误"不兼容类型的分配".

4)预优化:

该单元独立于CPU,即有两种类型的优化

  1. 预优化(独立于CPU)
  2. 后优化(取决于CPU)

此单元以下列形式优化代码:

  • I)消除死代码
  • II)子代码消除
  • III)循环优化

I)死代码消除:

例如:

{
    int a = 10;
    if ( a > 5 ) {
        /*
        ...
        */
    } else {
       /*
       ...
       */
    }
}
Run Code Online (Sandbox Code Playgroud)

这里,编译器在编译时知道'a'的值,因此它也知道if条件总是为真.因此它消除了代码中的else部分.

II)子代码消除:

例如:

{
    int a, b, c;
    int x, y;

    /*
    ...
    */

    x = a + b;
    y = a + b + c;

    /*
    ...
    */
}
Run Code Online (Sandbox Code Playgroud)

可以如下优化:

{
    int a, b, c;
    int x, y;

    /*
     ...
    */

    x = a + b;
    y = x + c;      // a + b is replaced by x

    /*
     ...
    */
}
Run Code Online (Sandbox Code Playgroud)

III)循环优化:

例如:

{
    int a;
    for (i = 0; i < 1000; i++ ) {

    /*
     ...
    */

    a = 10;

    /*
     ...
    */
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,如果'a'是本地的而不是在循环中使用,那么它可以如下优化:

{
    int a;
    a = 10;
    for (i = 0; i < 1000; i++ ) {
        /*
        ...
        */
    }
}
Run Code Online (Sandbox Code Playgroud)

5)代码生成:

这里,编译器生成汇编代码,以便更频繁使用的变量存储在寄存器中.

6)后优化:

这里的优化与CPU有关.假设代码中有多个跳转,那么它们将被转换为一个:

            -----
        jmp:<addr1>
<addr1> jmp:<addr2>
            -----
            -----
Run Code Online (Sandbox Code Playgroud)

控件直接跳转到.

然后最后一个阶段是链接(创建可执行文件或库).运行可执行文件时,它需要的库是Loaded.

  • 我不确定为什么还有人没有指出,但链接器和加载器不是同一步.链接是编译的一部分,而加载是(在运行程序之前)的一部分. (6认同)

Too*_*the 121

  • 编译器读取,分析代码并将其转换为目标文件或错误消息列表.
  • 链接器将一个或多个目标文件和可能的一些库代码组合成一些可执行文件,一些库或错误消息列表.
  • 加载程序将可执行代码读入内存,执行某些地址转换并尝试运行程序,从而导致运行程序或错误消息(或两者).

ASCII表示:

[Source Code] ---> Compiler ---> [Object code] --*
                                                 |
[Source Code] ---> Compiler ---> [Object code] --*--> Linker --> [Executable] ---> Loader 
                                                 |                                    |
[Source Code] ---> Compiler ---> [Object code] --*                                    |
                                                 |                                    |
                                 [Library file]--*                                    V
                                                                       [Running Executable in Memory]
Run Code Online (Sandbox Code Playgroud)

  • 这个解释很简单.你应该考虑成为一名讲师.谢谢 (2认同)

Anu*_*uni 29

希望这能帮到你一点点.

首先,看看这个图:

                         (img source->internet)
Run Code Online (Sandbox Code Playgroud)

源 - >互联网

然后,您创建一段代码并保存文件(源代码)

预处理: - 顾名思义,它不是编译的一部分.它们指示编译器在实际编译之前进行必要的预处理.您可以调用此阶段文本替换或解释由#表示的特殊预处理程序指令.

编译: - 编译是一种用一种语言编写的程序被翻译成另一种目标语言的过程.如果存在一些错误,编译器将检测它们并报告它.

汇编: - 汇编代码转换为机器代码.您可以将汇编程序称为特殊类型的编译器.

链接: - 如果这些代码需要链接其他一些源文件,链接器会链接它们以使其成为可执行文件.

之后会发生很多过程.是的,你猜对了装载机的作用:

Loader: - 将可执行代码加载到内存中; 创建程序和数据堆栈,初始化寄存器.

小额外信息: - http://www.geeksforgeeks.org/memory-layout-of-c-program/,你可以在那里看到内存布局.


Tan*_*ena 15

编译器:这是一个将高级语言程序翻译成机器语言程序的程序.编译器比汇编器更智能.它检查各种限制,范围,错误等.但它的程序运行时间更长,并占据更大的内存部分.它的速度很慢.因为编译器遍历整个程序,然后将整个程序转换为机器代码.如果编译器在计算机上运行并为同一台计算机生成机器代码,那么它就被称为自编译器或驻留编译器.另一方面,如果编译器在计算机上运行并为其他计算机生成机器代码,那么它被称为交叉编译器.

链接器:在高级语言中,存储了一些内置的头文件或库.这些库是预定义的,它们包含对执行程序至关重要的基本功能.这些函数通过名为Linker的程序链接到库.如果链接器找不到函数库,则它会通知编译器,然后编译器会生成错误.编译器会自动调用链接器作为编译程序的最后一步.它不是内置的库,它还将用户定义的函数链接到用户定义的库.通常,较长的程序被分成称为模块的较小子程序.并且必须组合这些模块来执行程序.组合模块的过程由链接器完成.

Loader:Loader是一个程序,它将程序的机器代码加载到系统内存中.在计算中,加载器是负责加载程序的操作系统的一部分.这是启动计划过程中的重要阶段之一.因为它将程序放入内存并准备执行.加载程序涉及将可执行文件的内容读入内存.加载完成后,操作系统通过将控制权传递给加载的程序代码来启动程序.支持程序加载的所有操作系统都有加载器.在许多操作系统中,加载器永久驻留在存储器中.


Red*_*ick 12

维基百科应该有一个很好的答案,这是我的想法:

  • 编译器:读取something.c source,写something.o对象.
  • 链接器:将几个*.o文件连接到可执行程序中.
  • Loader:将可执行文件加载到内存并启动它运行的代码.


tse*_*thy 5

*

相对于基于 linux/unix 的系统进行了解释,尽管它是所有其他计算系统的基本概念。

*

LinuxJournal 的链接器和加载器清晰地解释了这个概念。它还解释了经典名称 a.out 的来历。(汇编输出)

快速总结,

c program --> [compiler] --> objectFile --> [linker] --> executable file (say, a.out)

我们得到了可执行文件,现在将此文件提供给您的朋友或需要此软件的客户:)

当他们运行这个软件时,比如在命令行中输入 ./a.out

execute in command line ./a.out --> [Loader] --> [execve] --> program is loaded in memory

一旦程序被加载到内存中,通过使 PC(程序计数器)指向程序的第一条指令,控制权被转移到该程序。 a.out