程序的翻译环境和执行环境
文章目录
前言
本文主要介绍程序的两种环境:翻译环境和执行环境
一、翻译环境和执行环境的区别是什么?
在翻译环境中源代码被转换为可执行的机器指令,也就是二进制指令。
而执行环境是用于实际的执行代码
二、翻译环境
1.编译器和连接器
大家所熟知的编译器,例如vs2019、Dev c++、codeBlocks、Clion都是集成开发环境-IDE
功能:编辑、编译、链接、调试等
而我目前用的vs2019中编译器是cl.exe,链接器是link.exe
codeBlocks用的编译器是gcc,Clion的编译器是clang
2.链接库
链接库是库函数以外的库文件和第三方的库。比如MSDN中的fread
3.Linux gcc演示翻译环境
vs2019是一个集成开发环境,不易观察每个细节,我们使用Linux gcc来演示编译和链接。
(1)预编译
预编译指令:gcc test.c -E 回车
预编译结果:gcc test.c -E -o test.i 回车
注意:在Linux环境下,头文件放在/usr/include
注意:#define 预处理指令会直接替换!
(2)编译
编译之后停下来的指令:gcc test.i -s / gcc add.i -s(生成test.s和add.s两个文件)
注意:编译是把C语言代码翻译成汇编代码
{1.语法分析 2.词法分析 3.语义分析 4.符号汇总}
(3)汇编
让汇编停下来的代码:gcc test.s -c 和 gcc add.s -c分别转换成test.o和add.o
Windows环境下的目标文件是xxx.obj,Linux环境下的目标文件是xxx.o
汇编:吧汇编指令翻译成二进制的指令。在Linux环境瞎test.o可执行程序的格式是:elf,工具是readelf
这里有很多的指令,我们输入readelf test.o -s
那么我们应该理解main和Add符号表的作用
(4)链接
1.合并段表。2.符号表的合并和符号表的重定位
[1]合并段表
[2]符号表的合并和符号表的重定位
三、运行环境
程序执行的过程介绍
1.在有操作系统的环境中,程序载入内存由操作系统来完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成
2.程序的执行便开始,接着调用main函数
3.开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回
地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程
一直保留他们的值。
4.终止程序。正常终止main函数;也有可能是意外终止。
代码如下(示例):
void test()
{
int* p = (int*)malloc(100);
//忘记free释放
}
int main()
{
test();
while (1)
{
;
}
return 0;
}
这里的问题就是调用完test函数之后p的地址也跟着一起销毁,并且malloc开辟的空间也没有被free释放掉,
这样就会产生内存泄漏的问题!
内存泄漏是很危险的事情,当内存被消耗干的时候,操作系统就无法完成正常的运转!也会导致main函数意外终止
总结
例如:以上就是今天要讲的内容,本文仅仅简单介绍了程序环境中的两种环境:翻译环境和执行环境
如果我的博客对你有所帮助记得三连支持一下,感谢大家的支持!