今天收集了资料研究了下,希望以后扩充。
先说编译回顾下。1、预处理 2、编译(汇编生成)3、汇编(机器指令)4、链接
再说说二进制文件。
对于一个程序有四个空间:
栈: 由操作系统提供,是个数据结构。底层支持,专门寄存器处理。先进后出。
堆:任意存取,首地址记录堆空间大小,可以动态扩容。由c/c++提供实现,设有专门算法进行分配销毁,有记录链表。(方式地址到高地址遍历).我在windows上用vc和vs2012发现堆空间的遍历是高地址到底地址,而我在Ubuntu上发现堆空间的遍历是底地址到高地址(是操作系统的原因?)
数据段:
1、只读数据段;const修饰变量(不会被更改)
2、已初始化读写数据段;静态变量被初始化/全局变量被初始化
3、未被初始化数据段;静态、全局变量未被初始化。(Linux下有bss段保存)
程序代码区:函数体二进制代码。
然后我们讲下函数调用:
压入参数(顺序视编译器而定;一般从右到左)
压入函数返回值地址
开辟栈空间,根据压入参数,执行函数二进制代码
回收栈堆空间,返回返回值
然后讲程序调用:
我认为在程序开始时,堆空间会一起开辟;但根据代码运行开辟;但必须有一个记录链表(c/c++实现)。 遇见开辟堆空间时,算法先找到第一个满足大小的连续空间来开辟到程序堆空间。若没有就优化碎片,再遍历。所以需要程序自己free内存来从链表删除,系统添加。
所谓的内存泄露,我想也是链表上还存在内存地址吧!
操作系统也是有链表来记录空闲空间的,来分配和扩容。