[CRT]
[reactos.git] / lib / sdk / crt / except / i386 / chkstk_asm.s
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Stack checker
6 * FILE: lib/ntdll/rtl/i386/chkstk.s
7 * PROGRAMER: KJK::Hyperion <noog@libero.it>
8 */
9
10 #include <reactos/asm.h>
11 #include <ndk/asm.h>
12 #define PAGE_SIZE 4096
13
14 PUBLIC __chkstk
15 PUBLIC __alloca_probe
16 .code
17
18 /*
19 _chkstk() is called by all stack allocations of more than 4 KB. It grows the
20 stack in areas of 4 KB each, trying to access each area. This ensures that the
21 guard page for the stack is hit, and the stack growing triggered
22 */
23 __chkstk:
24 __alloca_probe:
25
26 /* EAX = size to be allocated */
27 /* save the ECX register */
28 push ecx
29
30 /* ECX = top of the previous stack frame */
31 lea eax, [esp + 8]
32
33 /* probe the desired memory, page by page */
34 cmp eax, PAGE_SIZE
35 jge .l_MoreThanAPage
36 jmp .l_LessThanAPage
37
38 .l_MoreThanAPage:
39
40 /* raise the top of the stack by a page and probe */
41 sub ecx, PAGE_SIZE
42 test [ecx], eax
43
44 /* loop if still more than a page must be probed */
45 sub eax, PAGE_SIZE
46 cmp eax, PAGE_SIZE
47 jge .l_MoreThanAPage
48
49 .l_LessThanAPage:
50
51 /* raise the top of the stack by EAX bytes (size % 4096) and probe */
52 sub ecx, eax
53 test [ecx], eax
54
55 /* EAX = top of the stack */
56 mov eax, esp
57
58 /* allocate the memory */
59 mov esp, ecx
60
61 /* restore ECX */
62 mov ecx, [eax]
63
64 /* restore the return address */
65 mov eax, [eax + 4]
66 push eax
67
68 /* return */
69 ret
70
71 /* EOF */
72 END