第4部分库与运行库(第10章 内存)

来源:互联网 发布:马其顿 知乎 编辑:程序博客网 时间:2024/06/17 17:49

        一个程序能够需要依赖于内存、运行库、系统调用。在这里内存与程序的关系,好比鱼和水一般密不可分。内存是承载程序运行的介质,也是程序进行各种运算和表达的场所。

       其实看待一个东西都是一个从宏观到细节一步一步细化的过程。所以首先我们来看一个进程所对应的逻辑内存的布局是怎么样的。

      Windows在默认情况下会将高地址的2GB空间分配给内核(也可配置为1GB),而Linux默认情况下降高地址的1GB空间分配给内核。用户使用剩下的2GB或者3GB的内存空间称为用户空间。在用户空间里,也有许多地址区间有特殊的地位,一般来讲,应用程序使用的内存空间里有如下“默认”的区域。

  • 栈:栈用于维护函数调用的上下文,离开了栈函数调用就无法实现。栈通常在用户空间最高地址处分配,通常有数兆字节的大小。
  • 堆:堆是用来容纳应用程序动态分配的内存区域,当程序使用malloc或new分配内存时,得到的内存来自堆里。堆通常存在于栈的下发(低地址方向),在某些时候,堆也可能没有固定统一的存储区域。堆一般比栈大很多,可以有几十至数百字节的容量。
  • 可执行文件映像:这里存储着可执行文件在内存里的映像,由装载器在装载时将可执行文件的内存读取或映射到这里。
  • 保留区:保留区并不是一个单一的内存区域,而是对内存中收到保护而禁止访问的内存区域的总称,例如,大多数操作系统里,极小的地址通常都是不允许访问的,如NULL,通常C语言将无效指针赋值为0也是出于这个考虑,因为0地址上正常情况下不可能有有效的可访问数据。


程序的内存布局

      程序调用会依赖一个重要的数据结构,称之为活动记录:


活动记录

【小知识】

       我们在VC下调试程序的时候,常常看到一些没有初始化的变量或内存区域的值是“烫”,例如下列代码:

int main(){char p[12];}

        此代码中的数组P没有初始化,当我们在Debug模式下运行这个程序,在main中设下断点并监视(watch)数组p时,就能看见如图的情形


未初始化的局部变量

       之所以会出现“烫”这么一个奇怪的字,就是因为Debug模式会将分配出来的栈空间的每一个字节都初始化为0xCC,oxCCCC的汉子编码就是烫,所以oxCCCC如果被当作文本就是“烫”。不过有时候会被置为oxCD,我们则会看到“屯”。


【小知识】Hot Patch Prologue


函数调用惯例

参考资料维基百科,一个调用惯例一般会规定如下几个方面的内容:

参数的传递顺序和方式

站的维护方式

名字修饰的策略

阅读全文
0 0
原创粉丝点击