源文件是如何通过编译器换成可执行文件的?
可执行文件被加载到内存后是如何运行的?
程序运行是内存上的栈和堆是如何进行的?
计算机只能运行本地代码(机器语言代码)
编译器负责转换源代码
读入的源代码还要经过语法解析、句法解析、语义解析等,才能生成本地代码
编译器不仅和编程语言的种类有关,和CPU的类型也是相关的。
仅靠编译是无法得到可执行文件的
本地文件是无法直接运行的,为了得到可以运行的EXE文件,编译之后还需要进行“链接”处理。
把多个目标文件结合,生成1个EXE文件的处理就是链接,运行连接的程序就称这链接器。
启动及库文件
c0w32.obj 这个目标文件记述的是同所有程序起始位置相结合的处理内容,程序的启动。
库文件指的是把多个目标文件集成保存到一个文件中的形式。链接器指定库文件后,就会从中把需要的目标文件抽取出来,并同其他目标文件结合生成EXE文件。
不是通过源代码形式而是通过库文件形式和编译器一起提供的的函数称为标准函数。
DLL文件及导入库
windows 以函数的形式为应用提供了各种功能。这些形式的函数称为API,并不是C语言的标准函数。
API的目标文件,并不是存储在通常的库文件中,而存储在名为DLL文件的特殊库文件中,这样的库文件称之为导入库。DLL文件是程序运行时动态结合的文件。(个人觉得可以理解为系统文件)
可执行文件运行时的必要条件
每次运行是,程序内的变量及函数被分配到的内存地址是不同的。那么在EXE文件中,变量和函数的内存地址的值,是如何来表示的呢?
答案就是EXE文件中给变量及函数分配了虚拟的内存地址。在程序运行时,虚拟的内存地址会转换成实际的内存地址。链接器会在EXE文件的开头,追加转换内存地址所需的必要信息。这个信息称为再配置信息。这个再配置信息,变成为了变量和函数的相对地址。
程序加载时会生成栈和堆
当程序加载到内存后,除此之外还会额外生成两个组,那就栈和堆。栈是用来存储函数内部临时使用的变量(局部变量),以及函数调用时所用的参数的内存区域。堆是用来存储程序运行时的任意数据及对象的内存领域。
因此,内存中的程序,就是由用于变量的内存空间,用于函数的内存空间,用于栈的内存空间,用于堆的内存空间。当然加载操作系统的内存空间是另外一回事了。
栈中对数据进行存储和舍弃的代码,是由编译器自动生成的,不需要程序员参与。每当函数调用时会得到申请分配,函数处理完成后自动释放。堆则要根据程序员编写的程序,来明确进行申请分配或释放。
直接今天才对内存管理有了个基本清晰的了解,总算找到了一本说得清楚的书了。不过还是有点没太理解堆中的任意数据指的是?还有类和对象在内存的处理方式。