0、堆栈区域: 1M,x86下有256个页面
0x080FF000
0x080FE000
...
0x08001000
0x08000000
1、每当创建一个线程时,系统就会为线程的堆栈(每个线程有它自己的堆栈)保留一个堆栈空间区域,并将一些物理存储器提交给这个已保留的区域。按照默认设置,系统保留1 MB的地址空间并提交两个页面的内存。但是,这些默认值是可以修改的,方法是在你链接应用程序时设定M i c r o s o f t的链接程序的/ S TA C K选项。
2、每当线程试图访问保护页面中的存储器时,系统就会得到关于这个情况的通知。作为响应,系统将提交紧靠保护页面下面的另一个存储器页面。然后,系统从当前保护页面中删除保护页面的保护标志,并将它赋予新提交的存储器页面。这种方法使得堆栈存储器只有在线程需要时才会增加。
3、当系统将物理存储器提交给0 x 0 8 0 0 1 0 0 0地址上的页面时,它必须再执行一个操作,即它要引发一个E X C E P T I O N _ S TA C K _ O V E R F L O W 异常处理(在Wi n N T. h 文件中定义为0 x C 0 0 0 0 0 F D)。通过使用结构化异常处理( S E H),你的程序将能得到关于这个异常处理条件的通知,并且能够实现适度恢复。
4、堆栈区域的最后一个页面(0 x 0 8 0 0 0 0 0 0)始终被保留着。这样做的目的是为了防止不小心改写进程使用的其他数据。可以看到,在0 x 0 7 F F 0 0 0这个地址上( 0 x 0 8 0 0 0 0 0 0下面的一个页面),另一个地址空间区域已经提交了物理存储器。如果0 x 0 8 0 0 0 0 0 0地址上的页面包含物理存储器,系统将无法抓住线程访问已保留堆栈区域的尝试。如果堆栈深入到已保留堆栈区域的下面,那么线程中的代码就会改写进程的地址空间中的其他数据,这是个非常难以抓住的错误。
5、当编译程序时,编译器知道你针对的C P U系统的页面大小。x 8 6编译器知道页面大小是4K B,A l p h a编译器知道页面大小是8 KB。当编译器遇到程序中的每个函数时,它能确定该函数需要的堆栈空间的数量。如果该函数需要的堆栈空间大于目标系统的页面大小,编译器将自动插入对堆栈检查函数的调用。
6、如果在线程试图访问该堆栈时引发了这个访问违规异常条件,线程就会陷入很大的麻烦之中。这时,系统就会接管控制权,并终止进程的运行—不仅终止线程的运行,而切终止整个进程的运行。系统甚至不向用户显示一个消息框,整个进程都消失了!