Mercurial > pub > dyncall > dyncall
comparison doc/disas_examples/x86.cdecl.disas @ 469:984e6652b975
some x86 disas examples, for completion but also while researching struct by val passing on non-x64
author | Tassilo Philipp |
---|---|
date | Mon, 07 Feb 2022 13:15:49 +0100 |
parents | c0390dc85a07 |
children | 4e84d6faed54 |
comparison
equal
deleted
inserted
replaced
468:79b95db3d68f | 469:984e6652b975 |
---|---|
1 ; #include <stdlib.h> | 1 ; #include <stdlib.h> |
2 ; | 2 ; |
3 ; void leaf_call(int b, int c, int d, int e, int f, int g, int h) | 3 ; void leaf_call(int b, int c, int d, int e, int f, int g, int h) |
4 ; { | 4 ; { |
5 ; } | 5 ; } |
6 ; | 6 ; |
7 ; void nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h) | 7 ; void nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h) |
8 ; { | 8 ; { |
9 ; /* use some local data */ | 9 ; /* use some local data */ |
10 ; *(char*)alloca(220) = 'L'; | 10 ; *(char*)alloca(220) = 'L'; |
11 ; leaf_call(b, c, d, e, f, g, h); | 11 ; leaf_call(b, c, d, e, f, g, h); |
12 ; } | 12 ; } |
13 ; | 13 ; |
14 ; int main() | 14 ; int main() |
15 ; { | 15 ; { |
16 ; nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7); | 16 ; nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7); |
17 ; return 0; | 17 ; return 0; |
18 ; } | 18 ; } |
482 b1: c9 leave | 482 b1: c9 leave |
483 b2: c3 ret | 483 b2: c3 ret |
484 | 484 |
485 | 485 |
486 | 486 |
487 ; @@@ windows missing | 487 ; output from godbolt compiler explorer w/ msvc 19.0 |
488 | |
489 _leaf_call PROC | |
490 push ebp | |
491 mov ebp, esp | |
492 pop ebp | |
493 ret 0 | |
494 _leaf_call ENDP | |
495 | |
496 _b$ = 12 | |
497 _c$ = 16 | |
498 _d$ = 20 | |
499 _e$ = 24 | |
500 _f$ = 28 | |
501 _g$ = 32 | |
502 _h$ = 36 | |
503 _nonleaf_call PROC | |
504 push ebp | |
505 mov ebp, esp | |
506 push 220 | |
507 call _alloca | |
508 add esp, 4 | |
509 mov BYTE PTR [eax], 76 | |
510 mov eax, DWORD PTR _h$[ebp] | |
511 push eax | |
512 mov ecx, DWORD PTR _g$[ebp] | |
513 push ecx | |
514 mov edx, DWORD PTR _f$[ebp] | |
515 push edx | |
516 mov eax, DWORD PTR _e$[ebp] | |
517 push eax | |
518 mov ecx, DWORD PTR _d$[ebp] | |
519 push ecx | |
520 mov edx, DWORD PTR _c$[ebp] | |
521 push edx | |
522 mov eax, DWORD PTR _b$[ebp] | |
523 push eax | |
524 call _leaf_call | |
525 add esp, 28 | |
526 pop ebp | |
527 ret 0 | |
528 _nonleaf_call ENDP | |
529 | |
530 _main PROC | |
531 push ebp | |
532 mov ebp, esp | |
533 push 7 | |
534 push 6 | |
535 push 5 | |
536 push 4 | |
537 push 3 | |
538 push 2 | |
539 push 1 | |
540 push 0 | |
541 call _nonleaf_call | |
542 add esp, 32 | |
543 xor eax, eax | |
544 pop ebp | |
545 ret 0 | |
546 _main ENDP | |
547 | |
548 | |
549 | |
550 ; ---------- structs by value, struct in first call on reg arg boundary ----------> | |
551 ; | |
552 ; struct A { int x; short y; char z; long long t; }; | |
553 ; | |
554 ; struct A leaf_call(struct A a, short b, long long c, char d, int e, int f, int g, long long h) | |
555 ; { | |
556 ; a.x += 1; | |
557 ; return a; | |
558 ; } | |
559 ; | |
560 ; int main() | |
561 ; { | |
562 ; struct A a ={9, 99, 23, 12LL}; | |
563 ; leaf_call(a, 1, 2, 3, 4, 5, 6, 7LL); | |
564 ; return 0; | |
565 ; } | |
566 | |
567 | |
568 | |
569 ; output from godbolt compiler explorer w/ msvc 19.0 | |
570 | |
571 $T1 = 8 | |
572 _a$ = 12 | |
573 _leaf_call PROC | |
574 push ebp ; | prolog | |
575 mov ebp, esp ; / | |
576 mov eax, DWORD PTR _a$[ebp] ; \ | |
577 add eax, 1 ; | get struct's x (from stack args), add 1 and write back | |
578 mov DWORD PTR _a$[ebp], eax ; / | |
579 mov ecx, DWORD PTR $T1[ebp] ; get ptr to retval struct passed as hidden arg (+8 to skip retval and saved ebp) | |
580 mov edx, DWORD PTR _a$[ebp] ; | | |
581 mov DWORD PTR [ecx], edx ; | | |
582 mov eax, DWORD PTR _a$[ebp+4] ; | | |
583 mov DWORD PTR [ecx+4], eax ; | copy modified (b/c of x+=1) struct arg to space of retval | |
584 mov edx, DWORD PTR _a$[ebp+8] ; | | |
585 mov DWORD PTR [ecx+8], edx ; | | |
586 mov eax, DWORD PTR _a$[ebp+12] ; | | |
587 mov DWORD PTR [ecx+12], eax ; | | |
588 mov eax, DWORD PTR $T1[ebp] ; return value (= ptr to struct that was passed-in as hidden arg) | |
589 pop ebp ; | | |
590 ret 0 ; | epilog | |
591 _leaf_call ENDP | |
592 | |
593 $T1 = -32 | |
594 _a$ = -16 | |
595 _main PROC | |
596 push ebp ; | | |
597 mov ebp, esp ; | prolog | |
598 sub esp, 32 ; / 32 = 16b local area for struct + 16b space used for retval struct | |
599 mov DWORD PTR _a$[ebp], 9 ; \ int x | |
600 mov eax, 99 ; | | | |
601 mov WORD PTR _a$[ebp+4], ax ; | struct values (local area) | short y | |
602 mov BYTE PTR _a$[ebp+6], 23 ; | char z | |
603 mov DWORD PTR _a$[ebp+8], 12 ; | | | |
604 mov DWORD PTR _a$[ebp+12], 0 ; / | long long t | |
605 push 0 ; \ | |
606 push 7 ; | arg 7 | |
607 push 6 ; arg 6 | |
608 push 5 ; arg 5 | |
609 push 4 ; arg 4 | |
610 push 3 ; arg 3 | |
611 push 0 ; | | |
612 push 2 ; arg 2 | |
613 push 1 ; arg 1 | |
614 sub esp, 16 ; | | |
615 mov ecx, esp ; | | |
616 mov edx, DWORD PTR _a$[ebp] ; | | |
617 mov DWORD PTR [ecx], edx ; | | |
618 mov eax, DWORD PTR _a$[ebp+4] ; | | |
619 mov DWORD PTR [ecx+4], eax ; | arg 0 (struct), "pushed" onto stack (fetched from local area) | |
620 mov edx, DWORD PTR _a$[ebp+8] ; | | |
621 mov DWORD PTR [ecx+8], edx ; | | |
622 mov eax, DWORD PTR _a$[ebp+12] ; | | |
623 mov DWORD PTR [ecx+12], eax ; / | |
624 lea ecx, DWORD PTR $T1[ebp] ; \ ptr to space used for struct retval (pushed as hidden first arg) | |
625 push ecx | | |
626 call _leaf_call ; push return address and call | |
627 add esp, 56 ; | | |
628 xor eax, eax ; : return value | |
629 mov esp, ebp ; | | |
630 pop ebp ; | epilog | |
631 ret 0 ; | | |
632 _main ENDP | |
633 | |
634 | |
488 | 635 |
489 ; vim: ft=asm | 636 ; vim: ft=asm |
490 | 637 |