2 ; Copyright Oliver Kowalke 2009.
3 ; Distributed under the Boost Software License, Version 1.0.
4 ; (See accompanying file LICENSE_1_0.txt or copy at
5 ; http://www.boost.org/LICENSE_1_0.txt)
7 ; --------------------------------------------------------------
8 ; | 0 | 1 | 2 | 3 | 4 | 5 |
9 ; --------------------------------------------------------------
10 ; | 0h | 04h | 08h | 0ch | 010h | 014h |
11 ; --------------------------------------------------------------
12 ; | EDI | ESI | EBX | EBP | ESP | EIP |
13 ; --------------------------------------------------------------
14 ; --------------------------------------------------------------
16 ; --------------------------------------------------------------
18 ; --------------------------------------------------------------
19 ; | ss_base | ss_limit| |
20 ; --------------------------------------------------------------
21 ; --------------------------------------------------------------
23 ; --------------------------------------------------------------
25 ; --------------------------------------------------------------
27 ; --------------------------------------------------------------
28 ; --------------------------------------------------------------
30 ; --------------------------------------------------------------
32 ; --------------------------------------------------------------
34 ; --------------------------------------------------------------
35 ; --------------------------------------------------------------
37 ; --------------------------------------------------------------
39 ; --------------------------------------------------------------
40 ; | fc_mxcsr|fc_x87_cw| |
41 ; --------------------------------------------------------------
46 _exit PROTO, value:SDWORD
47 align_stack PROTO, vp:DWORD
48 seh_fcontext PROTO, except:DWORD, frame:DWORD, context:DWORD, dispatch:DWORD
51 jump_fcontext PROC EXPORT
52 mov ecx, [esp+04h] ; load address of the first fcontext_t arg
53 mov [ecx], edi ; save EDI
54 mov [ecx+04h], esi ; save ESI
55 mov [ecx+08h], ebx ; save EBX
56 mov [ecx+0ch], ebp ; save EBP
59 mov edx, fs:[018h] ; load NT_TIB
61 mov eax, [edx] ; load current SEH exception list
62 mov [ecx+020h], eax ; save current exception list
63 mov eax, [edx+04h] ; load current stack base
64 mov [ecx+018h], eax ; save current stack base
65 mov eax, [edx+08h] ; load current stack limit
66 mov [ecx+01ch], eax ; save current stack limit
67 mov eax, [edx+010h] ; load fiber local storage
68 mov [ecx+024h], eax ; save fiber local storage
70 lea eax, [esp+04h] ; exclude the return address
71 mov [ecx+010h], eax ; save as stack pointer
72 mov eax, [esp] ; load return address
73 mov [ecx+014h], eax ; save return address
75 mov edx, [esp+08h] ; load address of the second fcontext_t arg
76 mov edi, [edx] ; restore EDI
77 mov esi, [edx+04h] ; restore ESI
78 mov ebx, [edx+08h] ; restore EBX
79 mov ebp, [edx+0ch] ; restore EBP
81 mov eax, [esp+010h] ; check if fpu enve preserving was requested
85 stmxcsr [ecx+028h] ; save MMX control word
86 fnstcw [ecx+02ch] ; save x87 control word
87 ldmxcsr [edx+028h] ; restore MMX control word
88 fldcw [edx+02ch] ; restore x87 control word
92 mov edx, fs:[018h] ; load NT_TIB
94 mov eax, [ecx+020h] ; load SEH exception list
95 mov [edx], eax ; restore next SEH item
96 mov eax, [ecx+018h] ; load stack base
97 mov [edx+04h], eax ; restore stack base
98 mov eax, [ecx+01ch] ; load stack limit
99 mov [edx+08h], eax ; restore stack limit
100 mov eax, [ecx+024h] ; load fiber local storage
101 mov [edx+010h], eax ; restore fiber local storage
103 mov eax, [esp+0ch] ; use third arg as return value after jump
105 mov esp, [ecx+010h] ; restore ESP
106 mov [esp+04h], eax ; use third arg as first arg in context function
107 mov ecx, [ecx+014h] ; fetch the address to return to
109 jmp ecx ; indirect jump to context
112 make_fcontext PROC EXPORT
113 mov eax, [esp+04h] ; load address of the fcontext_t arg0
114 mov [eax], eax ; save the address of passed context
115 mov ecx, [esp+08h] ; load the address of the context function
116 mov [eax+014h], ecx ; save the address of the context function
117 mov edx, [eax+018h] ; load the stack base
119 push eax ; save pointer to fcontext_t
120 push edx ; stack pointer as arg for align_stack
121 call align_stack ; align stack
122 mov edx, eax ; begin of aligned stack
123 pop eax ; remove arg for align_stack
124 pop eax ; restore pointer to fcontext_t
126 lea edx, [edx-014h] ; reserve space for last frame on stack, (ESP + 4) & 15 == 0
127 mov [eax+010h], edx ; save the aligned stack
129 mov ecx, seh_fcontext ; set ECX to exception-handler
130 mov [edx+0ch], ecx ; save ECX as SEH handler
131 mov ecx, 0ffffffffh ; set ECX to -1
132 mov [edx+08h], ecx ; save ECX as next SEH item
133 lea ecx, [edx+08h] ; load address of next SEH item
134 mov [eax+02ch], ecx ; save next SEH
136 stmxcsr [eax+028h] ; save MMX control word
137 fnstcw [eax+02ch] ; save x87 control word
139 mov ecx, finish ; address of finish
147 push eax ; exit code is zero
148 call _exit ; exit application