【程序运行时的两种环境】
目录:
- 前言
- 一、翻译环境
- (一)预编译
- (二)编译
- (三)汇编
- (四)链接
- 二、执行环境
- 三、补充
- 总结
前言
在ANSI C的任何一种实现中,都要经过两种环境:
一种是编译环境,用于将程序代码转换为可执行的机器指令(二进制指令),
另一种是执行环境,用于实际执行代码。
一、翻译环境
今天我们重点为理解翻译环境,下面是Windows环境下翻译阶段的过程图:
组成一个程序的每个源文件通过编译器编译分别转换成目标代码(object code),
每个目标文件通过链接器(linker)链接在一起,形成一个单一而完整的可执行程序,
链接器同时还会引入标准c函数库中任何被使用到的函数,而且链接器也可以检测程序员自己的程序库,
将其需要的函数链接到程序中。
下面是对编译环境各个过程的细分图:
(一)预编译
预编译操作:
- 将#include包含的头文件进行展开;(把头文件中的内容展开到源文件中)
- 将#define定义的常量和宏替换到程序中;
- 将程序中的注释全部替换为空格字符;
- 处理条件编译指令。(把该删除的代码删除掉,条件编译会在下一篇文章中详细说明)
(二)编译
编译操作:
- 语法分析
- 词法分析
- 语义分析
- 符号汇总(将本文件中的函数名和全局变量名都汇总在一起,之后的操作中会用到)
编译阶段会将程序代码转换为汇编代码。
补充:编译阶段只检验本文件中的语法是否有问题,并且进行符号汇总,不会检测使用的函数是否存在。
(三)汇编
汇编操作:
生成符号表(会将编译阶段汇总的符号加上地址)
汇编阶段会将汇编指令转换为二进制指令。
此时已经生成了目标文件
(四)链接
链接操作:
- 合并段表
- 符号表的汇总和符号表的重定位。(重定位就是查找该符号是否有定义)
将目标文件捆绑为可执行文件
二、执行环境
程序执行的过程:
- 程序必须载入内存才可执行。在有操作系统的环境下:这个操作一般由操作系统完成。
在独立程序中,载入过程必须手动完成,也可使用可执行代码载入只读内存中完成。- 程序的执行开始。调用main函数开始执行程序。
- 开始执行程序代码。函数执行过程中会调用运行时堆栈,存储函数的局部变量和返回地址。程序也可以使用静态内存(static),存储与静态内存中的变量在程序整个执行过程中一直存在。
- 终止程序。退出主函数,也可能会意外终止。
三、补充
由于博主的电脑上没有虚拟机所以很遗憾不能在LINUX环境中为大家进行演示,
下面是在LUNUX环境中的操作步骤,如果大家条件允许可以自行测试。
- 预处理 选项 gcc -E test.c -o test.i
预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中。- 编译 选项 gcc -S test.c
编译完成之后就停下来,结果保存在test.s中。- 汇编 gcc -c test.c
汇编完成之后就停下来,结果保存在test.o中。
总结
以上就是我们编译环境和运行环境的大致内容,如果有什么疑问或者建议都可以在评论区留言,感谢大家的支持,欢迎来评论区一起探讨,大家的鼓励是继续更新的巨大动力。