xp下用户程序空间分配(2):栈

快乐虾

http://blog.csdn.net/lights_joy/

[email protected]

本文适用于

Xp sp3

vs2008

欢迎转载,但请保留作者信息

每个线程都有自己的栈空间,这个空间大小是在CreateThread时指定的,而主线程的栈则是由xp在创建进程时指定的,在vs2008下设置一个断点,中断程序的执行,可以看到主线程ESP的值为0x00124914,这个指针落在下面这个区域:

基址

分配基址

分配保护

大小

状态

保护

类型

0011e000

00030000

00000004
PAGE_READWRITE

00012000

00001000
MEM_COMMIT

00000004
PAGE_READWRITE

00020000
MEM_PRIVATE

这块空间的上限是0x0013 0000,这个值与我们读出来的NT_TIB结构体里面的StackBase的值是一致的,也就是说主线程的栈空间从0x0013 0000开始往下增长。但是在NT_TIB里面的StackLimit值却只有0x00000 a000,很显然,可用的栈空间是不只这么一点的。

注意到上述内存区域的分配基址与这个内存区域的起始地址是不一样的,看看完整的内存块:

基址

分配基址

分配保护

大小

状态

保护

类型

00030000

00030000

00000004
PAGE_READWRITE

000ed000

00002000
MEM_RESERVE

00000000

00020000
MEM_PRIVATE

0011d000

00030000

00000004
PAGE_READWRITE

00001000

00001000
MEM_COMMIT

00000104
PAGE_READWRITE
PAGE_GUARD

00020000
MEM_PRIVATE

0011e000

00030000

00000004
PAGE_READWRITE

00012000

00001000
MEM_COMMIT

00000004
PAGE_READWRITE

00020000
MEM_PRIVATE

也就是说windows分配这块空间的时候是从0x0003 0000 ~ 0x0013 0000的,恰好1M,这也是默认情况下主线程的栈空间大小。但由于我们实际还没有使用这么大的栈空间,所以0x0003 0000开始的这一块空间的状态是MEM_RESERVE

再看中间的这个内存区域,它的保护标志多了个PAGE_GUARDMSDN里面这样解释这个标志位:

Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. Guard pages thus act as a one-time access alarm. For more information, see Creating Guard Pages.

When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

从这里大致可以知道,当ESP向下增长超过目前已经分配的空间,此时将触发一个异常,然后windows再调整这几块内存页的属性。当然,ESP的增长不能超过整个栈的大小,否则程序就无法继续了。

PAGE_GUARD的指引下,我们可以很轻易地从这些内存块中找出其它的栈:

基址

分配基址

分配保护

大小

状态

保护

类型

00390000

00390000

00000004
PAGE_READWRITE

0003c000

00002000
MEM_RESERVE

00000000

00020000
MEM_PRIVATE

003cc000

00390000

00000004
PAGE_READWRITE

00001000

00001000
MEM_COMMIT

00000104
PAGE_READWRITE
PAGE_GUARD

00020000
MEM_PRIVATE

003cd000

00390000

00000004
PAGE_READWRITE

00003000

00001000
MEM_COMMIT

00000004
PAGE_READWRITE

00020000
MEM_PRIVATE

这个栈属于另外一个线程,其大小为0x0003 c000,实际只使用了0x0000 3000

下面是另一个线程的栈:

基址

分配基址

分配保护

大小

状态

保护

类型

00c00000

00c00000

00000004
PAGE_READWRITE

000f9000

00002000
MEM_RESERVE

00000000

00020000
MEM_PRIVATE

00cf9000

00c00000

00000004
PAGE_READWRITE

00001000

00001000
MEM_COMMIT

00000104
PAGE_READWRITE
PAGE_GUARD

00020000
MEM_PRIVATE

00cfa000

00c00000

00000004
PAGE_READWRITE

00006000

00001000
MEM_COMMIT

00000004
PAGE_READWRITE

00020000
MEM_PRIVATE

总共三个栈空间,和程序里面的三个线程一一对应。

1 参考资料

xp下用户程序空间分配(1):大致框架(2009-8-26)

你可能感兴趣的:(框架,windows,.net,XP,Access)