首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是编译器、链接器、装载器?

什么是编译器、链接器、装载器?
EN

Stack Overflow用户
提问于 2010-10-22 20:12:55
回答 14查看 232.1K关注 0票数 114

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

EN

回答 14

Stack Overflow用户

发布于 2014-02-21 02:04:05

代码语言:javascript
复制
=====> 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)

C预处理器:

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

  1. #define statements.
  2. #include statements.
  3. Conditional statements.
  4. Macros

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

C编译:

单元中有六个步骤:

1)词法分析器:

它将源文件中的字符组合在一起,形成一个"TOKEN“。标记是一组不包含“空格”、“制表符”和“换行”的字符。因此,这个编译单元也被称为"TOKENIZER“。它还删除注释,生成符号表和重定位表条目。

2)语法分析器:

此单元检查代码中的语法。对于ex:

代码语言:javascript
复制
{
    int a;
    int b;
    int c;
    int d;

    d = a + b - c *   ;
}

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

代码语言:javascript
复制
                            =
                          /   \
                        d       -
                              /     \
                            +           *
                          /   \       /   \
                        a       b   c       ?

因此,这个单元也被称为解析器。

3)语义分析器:

本单元检查语句中的含义。对于ex:

代码语言:javascript
复制
{
    int i;
    int *p;

    p = i;
    -----
    -----
    -----
}

上面的代码生成错误“分配不兼容的类型”。

4)预优化:

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

  1. Preoptimization (CPU independent)
  2. Postoptimization (CPU相关)

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

循环i)死代码elimination

  • II)子代码elimination

  • III)

  • optimization

I)消除死码:

对于ex:

代码语言:javascript
复制
{
    int a = 10;
    if ( a > 5 ) {
        /*
        ...
        */
    } else {
       /*
       ...
       */
    }
}

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

II)子码消除:

对于ex:

代码语言:javascript
复制
{
    int a, b, c;
    int x, y;

    /*
    ...
    */

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

    /*
    ...
    */
}

可以按如下方式进行优化:

代码语言:javascript
复制
{
    int a, b, c;
    int x, y;

    /*
     ...
    */

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

    /*
     ...
    */
}

III)循环优化:

对于ex:

代码语言:javascript
复制
{
    int a;
    for (i = 0; i < 1000; i++ ) {

    /*
     ...
    */

    a = 10;

    /*
     ...
    */
    }
}

在上面的代码中,如果'a‘是本地的,并且没有在循环中使用,则可以按如下方式进行优化:

代码语言:javascript
复制
{
    int a;
    a = 10;
    for (i = 0; i < 1000; i++ ) {
        /*
        ...
        */
    }
}

5)代码生成:

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

6)优化后:

这里的优化依赖于CPU。假设代码中有多个跳转,则将它们转换为一个跳转,如下所示:

代码语言:javascript
复制
            -----
        jmp:<addr1>
<addr1> jmp:<addr2>
            -----
            -----

控件直接跳转到。

最后一个阶段是链接(创建可执行文件或库)。运行可执行文件时,会加载它所需的库。

票数 197
EN

Stack Overflow用户

发布于 2010-10-22 20:34:22

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

ASCII表示法:

代码语言:javascript
复制
[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]
票数 136
EN

Stack Overflow用户

发布于 2015-04-03 17:47:55

希望这对你有更多的帮助。

首先,看一下这个图表:

代码语言:javascript
复制
(img source->internet)

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

Preprocessing:顾名思义,它不是编译的一部分。它们指示编译器在实际编译之前进行所需的预处理。您可以将此阶段称为文本替换或解释由#表示的特殊预处理器指令。

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

汇编 :-汇编代码被翻译成机器码。你可以称汇编器为一种特殊类型的编译器。

Linking:如果这些代码需要链接其他源文件,则链接器将它们链接起来,使其成为可执行文件。

在它之后会发生很多过程。是的,你猜对了,这里就是装载器的角色:

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

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

票数 30
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3996651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档