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

释放双眼,带上耳机,听听看~!

我想深入了解编译器,链接器和加载器的意义和工作。
参考任何语言优选c。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
1=====> COMPILATION PROCESS <======
2
3                     |
4                     |---->  Input is Source file(.c)
5                     |
6                     V
7            +=================+
8            |                 |
9            | C Preprocessor  |
10            |                 |
11            +=================+
12                     |
13                     | ---> Pure C file ( comd:cc -E <file.name> )
14                     |
15                     V
16            +=================+
17            |                 |
18            | Lexical Analyzer|
19            |                 |
20            +-----------------+
21            |                 |
22            | Syntax Analyzer |
23            |                 |
24            +-----------------+
25            |                 |
26            | Semantic Analyze|
27            |                 |
28            +-----------------+
29            |                 |
30            | Pre Optimization|
31            |                 |
32            +-----------------+
33            |                 |
34            | Code generation |
35            |                 |
36            +-----------------+
37            |                 |
38            | Post Optimize   |
39            |                 |
40            +=================+
41                     |
42                     |--->  Assembly code (comd: cc -S <file.name> )
43                     |
44                     V
45            +=================+
46            |                 |
47            |   Assembler     |
48            |                 |
49            +=================+
50                     |
51                     |--->  Object file (.obj) (comd: cc -c <file.name>)
52                     |
53                     V
54            +=================+
55            |     Linker      |
56            |      and        |
57            |     loader      |
58            +=================+
59                     |
60                     |--->  Executable (.Exe/a.out) (com:cc <file.name> )
61                     |
62                     V
63            Executable file(a.out)
64

C预处理器: –

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

define语句。
include语句。
条件语句。

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

C编译:

单位有六个步骤:

1)词汇分析器:

它组合源文件中的字符,形成一个“TOKEN”。一个
令牌是一组不具有“空格”,“制表符”和“新行”的字符。
因此,这个编译单元也称为“TOKENIZER”。它也删除
注释,生成符号表和重定位表条目。

2)语法分析器:

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


1
2
3
4
5
6
7
8
9
1{
2    int a;
3    int b;
4    int c;
5    int d;
6
7    d = a + b - c *   ;
8}
9

上面的代码将生成解析错误,因为方程不是
均衡。此单元通过生成解析器树在内部检查
如下:


1
2
3
4
5
6
7
8
1=
2                          /   \
3                        d       -
4                              /     \
5                            +           *
6                          /   \       /   \
7                        a       b   c       ?
8

因此,该单位也称为PARSER。

3)语义分析器:

此单元检查语句中的含义。例如:


1
2
3
4
5
6
7
8
9
10
1{
2    int i;
3    int *p;
4
5    p = i;
6    -----
7    -----
8    -----
9}
10

上面的代码生成错误“Assignment of incompatible type”。

4)预优化:

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

优化(独立于CPU)
后优化(取决于CPU)

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

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

I)死代码消除:

例如:


1
2
3
4
5
6
7
8
9
10
11
12
13
1{
2    int a = 10;
3    if ( a > 5 ) {
4        /*
5        ...
6        */
7    } else {
8       /*
9       ...
10       */
11    }
12}
13

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

II)子代码消除:

例如:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1{
2    int a, b, c;
3    int x, y;
4
5    /*
6    ...
7    */
8
9    x = a + b;
10    y = a + b + c;
11
12    /*
13    ...
14    */
15}
16

可以优化如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1{
2    int a, b, c;
3    int x, y;
4
5    /*
6     ...
7    */
8
9    x = a + b;
10    y = x + c;      // a + b is replaced by x
11
12    /*
13     ...
14    */
15}
16

III)循环优化:

例如:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1{
2    int a;
3    for (i = 0; i < 1000; i++ ) {
4
5    /*
6     ...
7    */
8
9    a = 10;
10
11    /*
12     ...
13    */
14    }
15}
16

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


1
2
3
4
5
6
7
8
9
10
1{
2    int a;
3    a = 10;
4    for (i = 0; i < 1000; i++ ) {
5        /*
6        ...
7        */
8    }
9}
10

5)代码生成:

这里,编译器生成汇编代码使得更多
常用的变量存储在寄存器中。

6)后优化:

这里的优化是依赖于CPU。假设有多个
跳转到代码中,然后将它们转换为一个:


1
2
3
4
5
6
1-----
2        jmp:<addr1>
3<addr1> jmp:<addr2>
4            -----
5            -----
6

控制跳转到直接。

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

给TA打赏
共{{data.count}}人
人已打赏
安全经验

40行代码教你利用Python网络爬虫批量抓取小视频

2021-10-11 16:36:11

安全经验

安全咨询服务

2022-1-12 14:11:49

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索