欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux:预处理、编译、汇编、链接

程序员文章站 2022-04-21 23:26:18
...

从直观角度而言,编译器就是将高级语言翻译成机器语言(二进制)的一个工具。

C语言之经典“Hello World"可会写?入关第一天的挑战,相信大家已经可以信手拈来,那么你已经和我一样离成功不远了。

#include<stdio.h>

int main()
{
   printf("Hello World\n");
   return 0;
}

Linux下,我们可以用gcc一步就可生成可执行文件,事实上它是分为以下四部处理的。

1.预处理:生成.i文件(-E表示只进行预编译)

  gcc -E main.c -o main.i

2.编译:生成.s文件

  gcc -S main.i -o main.s

3.汇编:生成.o文件,即可重定位的二进制文件

  gcc -C main.s -o main.i

4.链接:生成可执行的elf格式文件

gcc main.c -o main

 

那么我们再从代码角度分析一下它的处理过程:

预处理阶段

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

2.处理所有预编译指令,如"#if" 、"#endif"等。

3.处理"#include"指令,过程是递归处理的。

4.删除所有的注释。

5.添加行号和文件标识。

6.保留所有的"#pragma",编译器要使用。

经过预编译后的.i文件不包含任何宏定义,因为所有的宏已经被展开,并且包含的文件也已经被插入到.i文件中。所以我们发现宏定义和头文件出错时,它就发生在预编译阶段。

编译阶段

1.词法分析

2.语法分析

3.语义分析

4.优化代码

5.汇总符号

汇编阶段

1.将汇编指令翻译成可重定位的二进制目标文件

2.生成符号表

3.生成各个段的section

链接阶段

1.合并各个section,调整段的大小以及起始位置

2.符号解析

3.分配地址和空间,找到符号对应的虚拟内存地址

4.符号重定位

程序链接完成后,生成的可执行文件都会有4G的虚拟地址空间。

虚拟地址空间

蓝色区域表示3G用户空间,绿色区域表示1G内核空间。

所有的进程都拥有属于自己的用户空间,但却共享一个内核空间。

 

Linux:预处理、编译、汇编、链接

 

可以阅读《程序员的自我修养》和《编译原理》了解更详细的编译原理知识。

相关标签: 程序