test.c(文本文件)------编译,链接--------> test.exe(二进制文件)------------运行----->
- 翻译环境:程序从源文件到可执行文件所依赖的环境
- 源代码翻译成可执行的机器指令
- 每个源文件,经过编译器 单独处理,生成相应的obj目标文件
- 每个目标文件,由连接器捆绑在一起,形成一个单一而完整的可执行程序
- 执行环境:程序执行所依赖的环境
编译:
- 预编译
gcc -E test.c -o test.i
预处理完就会停下来,结果放到test.i
- 包含头文件的内容
- 删除注释(使用空格替换注释)
- 预处理指令的处理
#define
,把这些值都替换好- 编译
gcc -S test.c
编译完成,结果放在test.s
- c代码翻译成汇编代码
- 语法分析、词法分析、语义分析、符号汇总(函数名,全局变量)…
- 汇编
gcc -c test.c
汇编完成之后,结果放在test.o
- 生成目标文件(二进制指令)
- 形成符号表(函数名,全局变量以及他们的地址)
链接:合并表段,符号表的合并和重定位
如果函数只声明,ADD,他的地址是个无意义的某个值,比如000,而我们对ADD函数的源文件也编译的时候,这里是函数ADD的定义,地址是个有意义的。然后将这两个地址进行合并,从而就能定位到我们定义的函数了。
执行环境
- 程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中 ,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
- 程序的执行便开始了,接着调用main函数
- 开始执行程序代码,这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程中一直保留他们的值。
- 终止程序,正常终止main函数;也有可能是意外终止。