编译与链接
- 前言
- 程序的环境
- 程序的编译与链接
- 写在最后
每当我们运行一段代码时,编译器都会自动的帮我们编译代码并将代码转换为一个二进制可执行文件(
.exe
), 有了这个可执行文件,便可以执行我们写的程序了。那么编译器对代码的编译以及生成可执行程序的过程是怎样的呢?这个问题便是本文章将要探讨的。
在ANSI C
的任何一种实现中,存在两个不同的环境,一种是翻译环境,一种是执行环境:
补充:
首先看看 翻译环境 的简图:
编译本身也分为几个阶段:
预编译 —> 编译 —> 汇编
预处理阶段要做的事情主要是这些:
#include
头文件的包含;#define
定义符号的替换和删除;接下来在linux
中用gcc编译器对一段代码进行预处理,如下:
预处理过后,我们观察test.i
这个预编译后的文件:
指令:gcc -E test.c -o test.i
可以看到,代码一下子膨胀了许多,这正是因为头文件被包含进来了,当来原先的
#define
与注释也不见了。
编译阶段是将C语言代码翻译成汇编代码, 其过程有:
符号汇总就是将相关的函数,以及全局变量汇总:
例如以下代码汇总后客观图:
将上述代码编译后:
指令:gcc -S test.c -o test.s
可以看到,C语言被翻译成了汇编代码。
test.o
);如下:
就将上述代码汇编,我们来看看test.o是不是二进制文件呢?
指令:gcc -c test.c -o test.o
可以看到,的确是一些二进制乱码。
通过编译的一系列过程后,接下来就是链接了
链接的相关过程有:
1. 合并段表(这里不解释,需了解细读《程序员的自我修养》这本书,里面对整个编译链接部分都有很详细的讲解)
2. 符号表的合并和重定位。
这里只讲解符号表的合并:
例如test1.c文件和test2.c文件的符号表合并过程:
最终,通过链接器和链接库将各个目标文件链接后形成可执行文件。
程序执行的过程:
如果说,你对这一块特别感兴趣,想继续深入,你可以读《程序员的自我修养》这本书,这本书里对这一块的知识有很详细的解析。
感谢阅读本小白的博客,错误的地方请严厉指出噢!
上一篇:读书思考:步步惊心的《技术陷阱》
下一篇:HybridCLR 热更新 笔记