文章目录
前言一、编译1.预编译(预处理)2.编译3.汇编 二、链接1.符号汇总2.符号表 总结前言
一个源文件想要变成可执行程序要经过两个过程:1.编译 2.链接。这两个过程都是在翻译环境下进行的。今天的主题是带大家了解翻译环境中的执行的具体操作。
一、编译
后续操作作将在Linux环境下演示。
1.预编译(预处理)
在Linux下创建一个test.c的文件。
预处理 选项 gcc -E test.c -o test.i
预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中。
打开test.i文件
这里我们会发现原来只有几行代码的test.c经过预处理生成的test.i文件内容居然有800多行之多。
我们不妨对比下test.c 与 test.i的内容
细心的小伙伴不难发现test.c中的<stdio.h> 和注释在经历过预处理在test.i中消失不见了,
其中<stdio.h>是在test.i中展开,所以导致其内容变的很多。
总结:1.头文件的包含 2.注释被删除 3.#define符号的替换(上述没有演示,读者可自行实践)
2.编译
编译 选项 gcc -S test.c
编译完成之后就停下来,结果保存在test.s中。
打开test.s
test.s中全是汇编代码
总结:编译过程中把C语言代码转变成汇编代码,详细过程1.语法分析2. 词法分析3.语义分析4.符号汇总
3.汇编
汇编 gcc -c test.c
汇编完成之后就停下来,结果保存在test.o中。
打开test.o
what!,很多读者看到这里或许和我一样吃惊,其实这都是二进制机器指令
总结:形成符号表。
二、链接
创建add.c文件进行上述类似操作
生成add.o文件(目标文件,windows中后缀为.obj)
执行gcc test.o add.o 将两个目标文件进行链接生成可执行程序a.out
执行a.out
成功打印数字5。
1.符号汇总
符号汇总出现在编译时期,就是将具有全局性质的符号进行汇总,如:上述test.c中的main , Add.
2.符号表
符号表作用就是对全局数据如Add 进行重定位。这也是为什么两个不同文件中不声明函数也能够运行的原因。
总结:1.合并段表 2.重定位
总结
感谢大家的观看,如有错误望指出!