В окнах стек (для определенного потока) увеличивается по требованию, пока не будет достигнут размер стека, указанный для этого потока до его создания.
Увеличение по требованию осуществляется с использованием защитных страниц, поскольку изначально имеется только фрагмент стека, за которым следует защитная страница, которая при попадании вызывает исключение - это исключение является специальным и обрабатывается система для вас - обработка увеличивает доступное пространство стека (также проверяется, достигнут ли предел!), и операция чтения повторяется.
Как только предел достигнут, больше нет роста, что приводит к исключению переполнения стека.
Текущее основание стека и лимит хранятся в блоке среды потока в структуре, называемой _NT_TIB
(блок информации о потоке).
Если у вас есть под рукой отладчик, вот что вы видите:
0:000> dt ntdll!_teb @$teb nttib.
+0x000 NtTib :
+0x000 ExceptionList : 0x0012e030 _EXCEPTION_REGISTRATION_RECORD
+0x004 StackBase : 0x00130000
+0x008 StackLimit : 0x0011e000
+0x00c SubSystemTib : (null)
+0x010 FiberData : 0x00001e00
+0x010 Version : 0x1e00
+0x014 ArbitraryUserPointer : (null)
+0x018 Self : 0x7ffdf000 _NT_TIB
Атрибут StackLimit будет обновляться по требованию.
Если вы проверите атрибуты в этом блоке памяти, вы увидите нечто похожее на это:
0:000> !address 0x0011e000
00030000 : 0011e000 - 00012000
Type 00020000 MEM_PRIVATE
Protect 00000004 PAGE_READWRITE
State 00001000 MEM_COMMIT
Usage RegionUsageStack
Pid.Tid abc.560
И проверка страницы рядом с ней выявляет атрибут охраны:
0:000> !address 0x0011e000-1000
00030000 : 0011d000 - 00001000
Type 00020000 MEM_PRIVATE
Protect 00000104 PAGE_READWRITE | PAGE_GUARD
State 00001000 MEM_COMMIT
Usage RegionUsageStack
Pid.Tid abc.560
Надеюсь, это поможет.