windows内存机制解析

windows内存机制解析

ID:9945262

大小:106.50 KB

页数:18页

时间:2018-05-16

windows内存机制解析_第1页
windows内存机制解析_第2页
windows内存机制解析_第3页
windows内存机制解析_第4页
windows内存机制解析_第5页
资源描述:

《windows内存机制解析》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、Windows内存机制解析Byleezy_200003-9-39:38前言 写这篇文章之前相当长的一段时间里,对windows内存机制是有着相当的困惑的。各个进程的内存空间是如何隔离和共享的?GDT(全局描述表)尚在,可分段机制去了那里?既然我们有虚拟的4G空间和结构化异常为何分配内存仍可能失败?在什么时候stack会溢出?―――当我把这些问题都弄清楚后,我写了这篇文章为自己做了个总结,希望对大家也有帮助。同时由于写Windows内存这块的文章比较多,我将尽力做到与别人的内容不重合。动笔后不久,我发现imquestion对于W

2、indows内存写了几篇非常不错的文章,总题目叫《JIURL玩玩Win2k内存篇》,推荐阅读。 一、总论 Windows内存管理机制,底层最核心的东西是分页机制。分页机制使每个进程有自己的4G虚拟空间,使我们可以用虚拟线性地址来跑程序。每个进程有自己的工作集,工作集中的数据可以指明虚拟线性地址对应到怎样的物理地址。进程切换的过程也就是工作集切换的过程,如MattPietrek所说如果只给出虚拟地址而不给出工作集,那这个地址是无意义的。(见图一) 在分页机制所形成的线性地址空间里,我们对内存进行进一步划分涉及的概念有堆、栈、自由

3、存储等。对堆进行操作的API有HeapCreate、HeapAlloc等。操纵自由存储的API有VirtualAlloc等。此外内存映射文件使用的也应该算是自由存储的空间。栈则用来存放函数参数和局部变量,随着stackframe的建立和销毁其自动进行增长和缩减。 说到这里,也许有人会提出疑问:对x86CPU分段机制是必须的,分页机制是可选的。为什么这里只提到了分页机制。那么我告诉你分段机制仍然存在,一是为了兼容以前的16位程序,二是Windows毕竟要区分ring0和ring3两个特权级。用SoftIce看一下GDT(全局描述

4、表)你基本上会看到如下内容: GDTbase=80036000Limit=03FF 0008Code32Base=00000000Lim=FFFFFFFFDPL=0PRE //内核态driver代码段 0010Data32Base=00000000Lim=FFFFFFFFDPL=0PRW//内核态driver的数据段 001BCode32Base=00000000Lim=FFFFFFFFDPL=3PRE//应用程序的代码段 0023Data32Base=00000000Lim=FFFFFFFFDPL=3PRW//应用程序的数据

5、段 这意味着什么呢? 我们再看一下线性地址的生成过程(见图一)。从中我们应该可以得出结论,如果segmengbaseaddress为0的话,那么这个段可以看作不存在,因为偏移地址就是最终的线性地址。 此外还有两个段存在用于KernelProcessorControlRegion和userthreadenvironmentblock。所以如果你在反汇编时看到MOVECX,FS:[2C]就不必惊讶,怎么这里使用逻辑地址而不是线性地址。在以后涉及异常处理的地方会对此再做说明。  二、从Stack说开去 从我个人的经验看,谈到内存时说

6、堆的文章最多,说stack的最少。我这里反其道而行的原因是stack其实要比堆更重要,可以有不使用堆的程序,但你不可能不使用stack,虽然由于对stack的管理是由编译器确定了的,进而他较少出错。 通过链接开关/STACK:reserve[,commit]可以指定进程主线程的stack大小,当你建立其他线程时如果不指定dwStackSize参数,则也将使用/STACK所指定的值。微软说,如果指定较大的commit值将有利于提升程序的速度,我没验证过,但理应如此。通常并不需要对STACK进行什么设定,缺省的情况下将保留1M空间

7、,并提交两个页(8Kforx86)。而1M空间对于大多数程序而言是足够的,但为防止stackoverflow有三点需要指出一是当需要非常大的空间时最好用全局数组或用VirtualAlloc进行分配,二是引用传递或用指针传递尺寸较大的函数参数(这点恐怕地球人都知道),三是进行深度递归时一定要考虑会不会产生stack溢出,如果有可能,可以采用我在《递归与goto》一文中提到的办法来仿真递归,这时候可以使用堆或自由存储来代替stack。同时结构化异常被用来控制是否为stack提交新的页面。(这部分写的比较简略因为很多人都写过,推荐阅

8、读JefferyRitcher《Windows核心编程》第16章) 下面我们来看一下stack的使用。假设我们有这样一个简单之极的函数:  int__stdcalladd_s(intx,inty){intsum; sum=x+y; returnsum;} 这样在调用函数前,通

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。