当系统创建线程时,会为线程栈预订一块地址空间(每个线程都有自己的栈), 并给区域调拔一些物理存储器。 默认会预订1MB的地址空间并给区域项部(即地址最高)的两个页面调拔存储器。在让线程开始执行之前,系统会把线程栈的指针指向区域顶部的那个页面的末尾(该地址非常接近0x08100000)。这个页面就是线程开始使用栈的地方。区域顶部往下的第二个页面被称这防护页面,随着线程调用越来越多的函数,调用树越来越深,也就都需要越来越多的栈空间。
当线程试图访问防护页面中的内存时,系统会得到通知,这时系统会先给防护页面下面的那个页面调拔存储器,接着去除当前防护页面的PAGE_GUARD保护属性标志,然后给刚调拔的存储页指定PAGE_GUARD保护属性标志,所以随着线程调用树变深,防护页面逐步下移, 栈空间也就越来越大。但是栈空间也不是会无限地增大,当系统给地址为0x0800100的页面调拔物理存储器时,接着系统会像上述的步骤一样,会将地址为0x08002000的页面的PAGE_GUARD保护属性标记去除掉,但是接下来不会给地址为0x0800100的页面指定PAGE_GUARD保护属性标志。这样做的为了避免栈溢出,为了保护进程的其它数据,使得不会因为意外的内存写越界而遭到破坏。