Mercurial > pub > dyncall > dyncall
annotate test/gen-masm/call_x86.S @ 663:127b569978cc default tip
- another tweak handling clang trying to be too smart (see last commit)
author | Tassilo Philipp |
---|---|
date | Sun, 24 Mar 2024 13:52:44 +0100 |
parents | da5232da6270 |
children |
rev | line source |
---|---|
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 | |
496
da5232da6270
- test code: rand-sig now spitting out dyncallish sigs (with ')' end delim and rettype at end), purely for consistency
Tassilo Philipp
parents:
281
diff
changeset
|
98 mov ebp, esp |
0 | 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 | |
496
da5232da6270
- test code: rand-sig now spitting out dyncallish sigs (with ')' end delim and rettype at end), purely for consistency
Tassilo Philipp
parents:
281
diff
changeset
|
200 mov ebp, esp |
0 | 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 | |
496
da5232da6270
- test code: rand-sig now spitting out dyncallish sigs (with ')' end delim and rettype at end), purely for consistency
Tassilo Philipp
parents:
281
diff
changeset
|
226 mov ebp, esp |
0 | 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 |