0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: test
|
|
5 File: test/gen-masm/call_x86.S
|
|
6 Description:
|
|
7 License:
|
|
8
|
281
|
9 Copyright (c) 2011-2018 Daniel Adler <dadler@uni-goettingen.de>,
|
0
|
10 Tassilo Philipp <tphilipp@potion-studios.com>
|
|
11
|
|
12 Permission to use, copy, modify, and distribute this software for any
|
|
13 purpose with or without fee is hereby granted, provided that the above
|
|
14 copyright notice and this permission notice appear in all copies.
|
|
15
|
|
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
23
|
|
24 */
|
|
25
|
|
26
|
|
27
|
|
28 #if defined(GEN_MASM)
|
|
29 .386
|
|
30 .MODEL FLAT
|
|
31 .CODE
|
|
32 # define BEGIN_ASM
|
|
33 # define END_ASM END
|
|
34 # define GLOBAL(X) _##X PROC
|
|
35 # define BEGIN_PROC(X) OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
|
36 # define END_PROC(X) _##X ENDP
|
|
37 # define HEX(X) X##h
|
|
38 #else
|
|
39 .intel_syntax
|
|
40 .text
|
|
41 # define BEGIN_ASM
|
|
42 # define END_ASM
|
|
43 # include "../../dyncall/dyncall_macros.h"
|
|
44 # if defined(DC__OS_Win32) || defined(DC__OS_Cygwin) || defined(DC__OS_MinGW) || defined(DC__OS_Darwin)
|
|
45 # define CSYM(X) _##X
|
|
46 # else
|
|
47 # define CSYM(X) X
|
|
48 # endif
|
|
49 # define GLOBAL(X) .globl CSYM(X)
|
|
50 # define BEGIN_PROC(X) CSYM(X):
|
|
51 # define END_PROC(X)
|
|
52 # define HEX(X) 0x##X
|
|
53 #endif
|
|
54
|
|
55 // Package: dyncall
|
|
56 // File: dyncall/dyncall_call_x86_gas.S
|
|
57 // Description: All x86 abi call kernel implementations in GNU Assembler using C Preprocessor
|
|
58 // License:
|
|
59 //
|
|
60 // Copyright (c) 2007-2010 Daniel Adler <dadler@uni-goettingen.de>,
|
|
61 // Tassilo Philipp <tphilipp@potion-studios.com>
|
|
62 //
|
|
63 // Permission to use, copy, modify, and distribute this software for any
|
|
64 // purpose with or without fee is hereby granted, provided that the above
|
|
65 // copyright notice and this permission notice appear in all copies.
|
|
66 //
|
|
67 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
68 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
69 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
70 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
71 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
72 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
73 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
74 //
|
|
75
|
|
76 // === end of macros ==========================================================
|
|
77
|
|
78 // ============================================================================
|
|
79 // DynCall Call Kernels for X86 Architecture
|
|
80 // ----------------------------------------------------------------------------
|
|
81 // C Interface:
|
|
82 // dcCall_x86_XXX(void* target, void* args, size_t size);
|
|
83 //
|
|
84 // Parameter Stack layout:
|
|
85 // size := ebp + 16
|
|
86 // args := ebp + 12
|
|
87 // target := ebp + 8
|
|
88 //
|
|
89 // NOTES:
|
|
90 // - epilog restore esp serves callee cleanup
|
|
91
|
|
92 // --- default / cdecl --------------------------------------------------------
|
|
93 // - caller clean-up
|
|
94 BEGIN_ASM
|
|
95 GLOBAL(dcCall_x86_cdecl)
|
|
96 BEGIN_PROC(dcCall_x86_cdecl)
|
|
97 push ebp // prolog
|
|
98 mov ebp, esp
|
|
99 push esi // save preserved
|
|
100 push edi
|
|
101 mov esi, dword ptr[ebp+12] // esi = copy source args
|
|
102 mov ecx, dword ptr[ebp+16] // ecx = size
|
|
103 sub esp, ecx // alloc stack size
|
|
104 mov edi, esp // edi = copy target stack
|
|
105 shr ecx, 2 // ecx = count DWORDs
|
|
106 rep movsd // copy DWORDs
|
|
107 call dword ptr[ebp+8] // call target
|
|
108 add esp, dword ptr[ebp+16] // cleanup stack
|
|
109 pop edi // restore preserved
|
|
110 pop esi
|
|
111 mov esp, ebp // epilog
|
|
112 pop ebp
|
|
113 ret
|
|
114 END_PROC(dcCall_x86_cdecl)
|
|
115
|
|
116 // ---- C++ this calls (microsoft) ------------------------------------------
|
|
117 // Details:
|
|
118 // - this pointer is in ECX
|
|
119
|
|
120 GLOBAL(dcCall_x86_win32_msthis)
|
|
121 BEGIN_PROC(dcCall_x86_win32_msthis)
|
|
122 push ebp // prolog
|
|
123 mov ebp, esp
|
|
124 push esi // save preserved
|
|
125 push edi
|
|
126 mov esi, dword ptr [ebp+12] // esi = pointer on args
|
|
127 mov ecx, dword ptr [ebp+16] // ecx = size
|
|
128 mov eax, dword ptr [esi+0] // eax = this pointer
|
|
129 add esi, 4 // increment args pointer by thisptr
|
|
130 sub ecx, 4 // decrement size by sizeof(thisptr)
|
|
131 sub esp, ecx // allocate argument-block on stack
|
|
132 mov edi, esp // edi = stack args
|
|
133 rep movsb // copy arguments
|
|
134 mov ecx, eax // ecx = this pointer
|
|
135 call dword ptr[ebp+8] // call function
|
|
136 pop edi // restore preserved
|
|
137 pop esi
|
|
138 mov esp, ebp // epilog
|
|
139 pop ebp
|
|
140 ret
|
|
141 END_PROC(dcCall_x86_win32_msthis)
|
|
142
|
|
143 // ---- win32 stdcall ---------------------------------------------------------
|
|
144 // - callee cleans up stack
|
|
145
|
|
146 GLOBAL(dcCall_x86_win32_std)
|
|
147 BEGIN_PROC(dcCall_x86_win32_std)
|
|
148 push ebp // prolog
|
|
149 mov ebp, esp
|
|
150 push esi // save esi, edi
|
|
151 push edi
|
|
152 mov esi, dword ptr[ebp+12] // esi = args
|
|
153 mov ecx, dword ptr[ebp+16] // ecx = size
|
|
154 sub esp, ecx // allocate size bytes on stack
|
|
155 mov edi, esp // edi = copy destination stack
|
|
156 rep movsb // copy BYTEs
|
|
157 call dword ptr[ebp+8] // call target
|
|
158 pop edi // restore edi, esi */
|
|
159 pop esi
|
|
160 mov esp, ebp // epilog
|
|
161 pop ebp
|
|
162 ret
|
|
163 END_PROC(dcCall_x86_win32_std)
|
|
164
|
|
165 // ---- win32 fastcall (GNU/Microsoft) ----------------------------------------
|
|
166 // - callee cleans up stack
|
|
167 // - first two integer (up to 32bits) are passed in ECX and EDX
|
|
168
|
|
169 GLOBAL(dcCall_x86_win32_fast)
|
|
170 BEGIN_PROC(dcCall_x86_win32_fast)
|
|
171 push ebp // prolog
|
|
172 mov ebp, esp
|
|
173 push esi // save preserved
|
|
174 push edi
|
|
175 mov esi, dword ptr[ebp+12] // esi = copy source args
|
|
176 mov ecx, dword ptr[ebp+16] // ecx = size
|
|
177 mov eax, dword ptr[esi+0] // eax = first argument
|
|
178 mov edx, dword ptr[esi+4] // edx = second argument
|
|
179 add esi, 8 // skip registers
|
|
180 sub ecx, 8 //
|
|
181 mov dword ptr [ebp+16], ecx // save stack alloc size
|
|
182 sub esp, ecx // allocate stack
|
|
183 mov edi, esp // edi = stack args
|
|
184 rep movsb // copy BYTEs
|
|
185 mov ecx, eax // ecx = first argument
|
|
186 call dword ptr[ebp+8] // call target
|
|
187 pop edi // restore preserved
|
|
188 pop esi
|
|
189 mov esp, ebp // epilog
|
|
190 pop ebp
|
|
191 ret
|
|
192 END_PROC(dcCall_x86_win32_fast)
|
|
193
|
|
194 // --- syscall int80 linux ---------------------------------------------------
|
|
195 // - all arguments are passed via registers
|
|
196
|
|
197 GLOBAL(dcCall_x86_sys_int80h_linux)
|
|
198 BEGIN_PROC(dcCall_x86_sys_int80h_linux)
|
|
199 push ebp // prolog
|
|
200 mov ebp, esp
|
|
201 push ebx // save preserved
|
|
202 push esi
|
|
203 push edi
|
|
204 mov eax, dword ptr[ebp+12] // eax = argument buffer
|
|
205 mov ebx, dword ptr[eax+0] // move first five arguments
|
|
206 mov ecx, dword ptr[eax+4]
|
|
207 mov edx, dword ptr[eax+8]
|
|
208 mov esi, dword ptr[eax+12]
|
|
209 mov edi, dword ptr[eax+16]
|
|
210 mov eax, dword ptr[ebp+8] // eax = syscall id
|
|
211 int HEX(80)
|
|
212 pop edi // restore preserved
|
|
213 pop esi
|
|
214 pop ebx
|
|
215 mov esp, ebp // epilog
|
|
216 pop ebp
|
|
217 ret
|
|
218 END_PROC(dcCall_x86_sys_int80h_linux)
|
|
219
|
|
220 // --- syscall int80 bsd -----------------------------------------------------
|
|
221 // - all arguments are passed via stack
|
|
222
|
|
223 GLOBAL(dcCall_x86_sys_int80h_bsd)
|
|
224 BEGIN_PROC(dcCall_x86_sys_int80h_bsd)
|
|
225 push ebp // prolog
|
|
226 mov ebp, esp
|
|
227 push esi // save preserved
|
|
228 push edi
|
|
229 mov esi, dword ptr[ebp+12] // esi = pointer on args
|
|
230 mov ecx, dword ptr[ebp+16] // ecx = size
|
|
231 sub esp, ecx // allocate stack space
|
|
232 mov edi, esp // edi = stack args
|
|
233 shr ecx, 2 // ecx = number of DWORDs
|
|
234 rep movsd // copy DWORDs
|
|
235 mov eax, dword ptr[ebp+8] // load system call id
|
|
236 call _do_int
|
|
237 pop edi // restore preserved
|
|
238 pop esi
|
|
239 mov esp, ebp // epilog
|
|
240 pop ebp
|
|
241 ret
|
|
242 _do_int:
|
|
243 int HEX(80)
|
|
244 ret
|
|
245 END_PROC(dcCall_x86_sys_int80h_bsd)
|
|
246 END_ASM
|