- Update to trunk
[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 <asm.inc>
11 #include <ks386.inc>
12
13 #define PAGE_SIZE 4096
14
15 PUBLIC __chkstk
16 PUBLIC __alloca_probe
17 PUBLIC __alloca_probe_16
18 .code
19
20 /* 16 byte aligned alloca probe
21 * EAX = size to be allocated */
22 __alloca_probe_16:
23 /* save the ECX register */
24 push ecx
25
26 /* ecx = top of the previous stack frame */
27 lea ecx, [esp + 8]
28
29 /* Calculate end of allocation */
30 sub ecx, eax
31
32 /* Get the misalignment */
33 and ecx, 15
34
35 /* Add the misalignment to the original alloc size */
36 add eax, ecx
37
38 /* Check for overflow */
39 jnc l1
40
41 /* Set maximum value */
42 mov eax, HEX(0ffffffff)
43 l1:
44 /* Restore ecx */
45 pop ecx
46 /* Fall through to __chkstk */
47
48 /*
49 _chkstk() is called by all stack allocations of more than 4 KB. It grows the
50 stack in areas of 4 KB each, trying to access each area. This ensures that the
51 guard page for the stack is hit, and the stack growing triggered
52 */
53 __chkstk:
54 __alloca_probe:
55
56 /* EAX = size to be allocated */
57 /* save the ECX register */
58 push ecx
59
60 /* ECX = top of the previous stack frame */
61 lea ecx, [esp + 8]
62
63 /* probe the desired memory, page by page */
64 cmp eax, PAGE_SIZE
65 jl .l_LessThanAPage
66
67 .l_MoreThanAPage:
68
69 /* raise the top of the stack by a page and probe */
70 sub ecx, PAGE_SIZE
71 test [ecx], eax
72
73 /* loop if still more than a page must be probed */
74 sub eax, PAGE_SIZE
75 cmp eax, PAGE_SIZE
76 jge .l_MoreThanAPage
77
78 .l_LessThanAPage:
79
80 /* raise the top of the stack by EAX bytes (size % 4096) and probe */
81 sub ecx, eax
82 test [ecx], eax
83
84 /* EAX = top of the stack */
85 mov eax, esp
86
87 /* allocate the memory */
88 mov esp, ecx
89
90 /* restore ECX */
91 mov ecx, [eax]
92
93 /* restore the return address */
94 mov eax, [eax + 4]
95 push eax
96
97 /* return */
98 ret
99
100 /* EOF */
101 END