comparison doc/disas_examples/x86.fastcall_ms.disas @ 530:585dcb68f55d

- more doc and disas examples for x86 fastcall and non-trivial aggregates
author Tassilo Philipp
date Sat, 16 Apr 2022 12:10:02 +0200
parents 79e76734bb5c
children
comparison
equal deleted inserted replaced
529:fe694c7677b4 530:585dcb68f55d
182 ret 0 ; | 182 ret 0 ; |
183 _main ENDP 183 _main ENDP
184 184
185 185
186 186
187 ; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
188 ;
189 ; struct Trivial { int a; };
190 ; struct NonTrivial {
191 ; int a;
192 ; NonTrivial() : a(0) {}
193 ; NonTrivial(const NonTrivial& rhs) : a(rhs.a) { }
194 ; };
195 ;
196 ; extern "C" {
197 ;
198 ; void f1(struct Trivial s) { }
199 ; void f2(struct NonTrivial s) { }
200 ;
201 ; void f()
202 ; {
203 ; struct Trivial t;
204 ; struct NonTrivial n;
205 ; int a=1;
206 ; a += 123;
207 ; f1(t);
208 ; a -= 123;
209 ; f2(n);
210 ; a -= 12;
211 ; }
212 ; }
213
214
215
216 ; output from godbolt compiler explorer w/ msvc 19.31 (/Gr for fastcall)
217
218 _this$ = -4
219 NonTrivial::NonTrivial(void) PROC
220 push ebp
221 mov ebp, esp
222 push ecx
223 mov DWORD PTR _this$[ebp], ecx
224 mov eax, DWORD PTR _this$[ebp]
225 mov DWORD PTR [eax], 0
226 mov eax, DWORD PTR _this$[ebp]
227 mov esp, ebp
228 pop ebp
229 ret 0
230 NonTrivial::NonTrivial(void) ENDP
231
232 _this$ = -4
233 _rhs$ = 8
234 NonTrivial::NonTrivial(NonTrivial const &) PROC
235 push ebp
236 mov ebp, esp
237 push ecx
238 mov DWORD PTR _this$[ebp], ecx
239 mov eax, DWORD PTR _this$[ebp]
240 mov ecx, DWORD PTR _rhs$[ebp]
241 mov edx, DWORD PTR [ecx]
242 mov DWORD PTR [eax], edx
243 mov eax, DWORD PTR _this$[ebp]
244 mov esp, ebp
245 pop ebp
246 ret 4
247 NonTrivial::NonTrivial(NonTrivial const &) ENDP
248
249 _s$ = 8
250 @f1@4 PROC
251 push ebp
252 mov ebp, esp
253 pop ebp
254 ret 4
255 @f1@4 ENDP
256
257 _s$ = 8
258 @f2@4 PROC
259 push ebp
260 mov ebp, esp
261 pop ebp
262 ret 4
263 @f2@4 ENDP
264
265 _t$ = -12
266 _n$ = -8
267 _a$ = -4
268 @f@0 PROC
269 push ebp ;
270 mov ebp, esp ;
271 sub esp, 12 ;
272 lea ecx, DWORD PTR _n$[ebp] ;
273 call NonTrivial::NonTrivial(void) ;
274 mov DWORD PTR _a$[ebp], 1 ;
275 mov eax, DWORD PTR _a$[ebp] ;
276 add eax, 123 ;
277 mov DWORD PTR _a$[ebp], eax ;
278 mov ecx, DWORD PTR _t$[ebp] ;
279 push ecx ;
280 call @f1@4 ;
281 mov edx, DWORD PTR _a$[ebp] ;
282 sub edx, 123 ;
283 mov DWORD PTR _a$[ebp], edx ;
284 push ecx ;
285 mov ecx, esp ;
286 lea eax, DWORD PTR _n$[ebp] ;
287 push eax ;
288 call NonTrivial::NonTrivial(NonTrivial const &) ;
289 call @f2@4 ;
290 mov ecx, DWORD PTR _a$[ebp] ;
291 sub ecx, 12 ;
292 mov DWORD PTR _a$[ebp], ecx ;
293 mov esp, ebp ;
294 pop ebp ;
295 ret 0 ;
296 @f@0 ENDP
297
298
299
300 ; ---------- C++ trivial and non-trivial aggrs as return values ---------->
301 ;
302 ; struct Trivial { int a; };
303 ; struct NonTrivial {
304 ; int a;
305 ; NonTrivial() : a(0) {}
306 ; NonTrivial(const NonTrivial& rhs) : a(rhs.a) { }
307 ; };
308 ;
309 ; extern "C" {
310 ; struct Trivial f1() { return Trivial(); }
311 ; }
312 ;
313 ; struct NonTrivial f2() { return NonTrivial(); }
314 ;
315 ; extern "C" {
316 ; void f()
317 ; {
318 ; int a=1;
319 ; a += 123;
320 ; struct Trivial t = f1();
321 ; a -= 123;
322 ; struct NonTrivial n = f2();
323 ; a -= 12;
324 ; }
325 ; }
326
327
328
329 ; output from godbolt compiler explorer w/ msvc 19.31 (/Gr for fastcall)
330
331 _this$ = -4
332 NonTrivial::NonTrivial(void) PROC
333 push ebp
334 mov ebp, esp
335 push ecx
336 mov DWORD PTR _this$[ebp], ecx
337 mov eax, DWORD PTR _this$[ebp]
338 mov DWORD PTR [eax], 0
339 mov eax, DWORD PTR _this$[ebp]
340 mov esp, ebp
341 pop ebp
342 ret 0
343 NonTrivial::NonTrivial(void) ENDP
344
345 $T1 = -4
346 @f1@0 PROC
347 push ebp
348 mov ebp, esp
349 push ecx
350 xor eax, eax
351 mov DWORD PTR $T1[ebp], eax
352 mov eax, DWORD PTR $T1[ebp]
353 mov esp, ebp
354 pop ebp
355 ret 0
356 @f1@0 ENDP
357
358 ___$ReturnUdt$ = -4
359 NonTrivial f2(void) PROC
360 push ebp ;
361 mov ebp, esp ;
362 push ecx ; ptr to hidden retval space as first arg (fastcall, in ecx)
363 mov DWORD PTR ___$ReturnUdt$[ebp], ecx ; |
364 mov ecx, DWORD PTR ___$ReturnUdt$[ebp] ; | a bit pointless
365 call NonTrivial::NonTrivial(void) ;
366 mov eax, DWORD PTR ___$ReturnUdt$[ebp] ; return passed-in ptr ptr to hidden retval space in eax
367 mov esp, ebp ;
368 pop ebp ;
369 ret 0 ;
370 NonTrivial f2(void) ENDP
371
372 _n$ = -16
373 _t$ = -12
374 $T1 = -8
375 _a$ = -4
376 @f@0 PROC
377 push ebp ;
378 mov ebp, esp ;
379 sub esp, 16 ;
380 mov DWORD PTR _a$[ebp], 1 ; a = 1
381 mov eax, DWORD PTR _a$[ebp] ; |
382 add eax, 123 ; | a += 123
383 mov DWORD PTR _a$[ebp], eax ; |
384 call @f1@0 ; call f1()
385 mov DWORD PTR $T1[ebp], eax ; retval (trivial struct <= 32bits, returned via eax)
386 mov ecx, DWORD PTR $T1[ebp] ; | copy of retval from stack to stack
387 mov DWORD PTR _t$[ebp], ecx ; /
388 mov edx, DWORD PTR _a$[ebp] ; \
389 sub edx, 123 ; | a -= 123
390 mov DWORD PTR _a$[ebp], edx ; |
391 lea ecx, DWORD PTR _n$[ebp] ; hidden first arg: ptr to space for (non-trivial) retval
392 call NonTrivial f2(void) ; call f2()
393 mov eax, DWORD PTR _a$[ebp] ; |
394 sub eax, 12 ; | a -= 12
395 mov DWORD PTR _a$[ebp], eax ; |
396 mov esp, ebp ;
397 pop ebp ;
398 ret 0 ;
399 @f@0 ENDP
400
401
402
187 ; vim: ft=asm 403 ; vim: ft=asm
188 404