理解编译器在编译过程中做了什么
来源:互联网 发布:数据差错检测 编辑:程序博客网 时间:2024/05/19 22:48
今年开了操作系统课,课上老师提了一个问题:从一个保存程序代码的文本文件到可执行的程序,编译器做了啥?由于之前买过<<深入了解计算机系统>>这本书,刚买来时受热就翻了其中一部分章节,其中就有讲到上述所问的讲解,索性就参考其上的讲解写出来
我会以一个hello.c的c程序贯穿整个文章,具体代码如下
#include<stdio.h>int main(int argc,char **argv){ printf("hello world\n"); return 0;}
该程序通过编译器编译生成hello程序,其运行结果如下
那么此程序从保存它的文本文件到可执行程序hello的中间编译器究竟做了啥,不说话先上图了
由上图可知gcc编译器驱动程序在读取了hello.c文件之后,把它翻译成了一个可执行代码。此过程共经历了4个阶段的程序,分别是预处理器,编译器,汇编器,链接器,此4个截断程序一起构成了编译系统。接下来我就为大家详细说明以下此4个阶段程序各自的具体工作
1.预处理阶段
预处理器会将以字符#开头的语句,修改为原始的c程序,比如hello.c中的#include
gcc -E hello.c -o hello.i
用vim打开hello.i文件之后如下图
这是文件开头
这是文件结尾处
我想大家一定会惊讶的发现一个简简单单的hello,world程序竟然会平白无辜的增加了800多行,没错这就是预处理器干的,它将程序中以#开头的stdio.h文件的内容都加了进来
需要强调的是,经预处理器的文件是文本文件
2.编译器
编译器会将上文中提到的hello.i(预编译好的文件)近一步翻译成保存汇编语言的文本,其后缀会变为.s
我们可以通过如下方式将hello.c编译成.s文件
gcc -S hello.c -o hello.s
打开hello.s文件如下图
可以看到里面的代码变为了汇编代码
需要注意的是.s文件依然是文本文件
3.汇编器
汇编器会将上述的hello.s文件翻译成机器语言指令,并把这些指令打包成一种叫做可重定位目标程序的格式并将结果保存在新生成的二进制文件hello.o中
4.链接阶
我们的程序hello中调用了printf函数,而printf函数存在于由c标准库提供的名为printf.o的单独预编译好了的目标文件中,所以我们要调用printf函数,就得通过链接器,使其通过它自己的方式将hello.o和printf.o这俩个文件合并在一起,经过合并后的文件就是可执行的hello文件了
- 理解编译器在编译过程中做了什么
- C语言编译过程中编译器都干了些什么?
- 当我们点击了编译时,编译器都为我们做了什么
- 在JSP编译的时候,服务器内部做了什么?
- 在JSP编译的时候,服务器内部做了什么?
- String拼接符"+"在编译期做了什么?
- oracle的commit过程中做了什么
- JVM中类加载过程都做了什么
- postgresql initdb过程中大体做了什么
- postgresql initdb过程中大体做了什么
- C/C++的编译过程中到底发生了什么?
- 【初级】C++中子类对象转型为父类对象时,编译器默默做了什么?
- 理解编译器的编译模板过程
- 理解编译器的编译模板过程
- 你知道编译器为我们做了些什么吗?
- C++编译器默默为你做了些什么?
- C++编译器创建的默认构造究竟做了什么??
- 编译器做些什么?
- 实现一个方法,搭出最高的一堆箱子,箱堆的高度为每个箱子高度的总和
- 《C++primer(第五版)》学习之路-序
- 内存 地址 分配
- enq: TM - contention TM 等待事件的原因及模拟(表外键约束无索引导致)
- 取消文件夹拒绝访问
- 理解编译器在编译过程中做了什么
- OC之内存管理
- 数据结构与算法分析Java版练习1.13
- 在线调试方案的思考与实践
- Google技巧之inurl
- Android应用程序用户界面(七)
- 【bzoj2818】【GCD】【数论】
- VC移动对话框到扩展屏幕,全屏显示
- GBDT(MART) 迭代决策树入门教程 | 简介