Dyn

 view release on metacpan or  search on metacpan

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

  59:   83 c4 10                add    $0x10,%esp
  5c:   c9                      leave
  5d:   c3                      ret

0000005e <main>:
  5e:   55                      push   %ebp
  5f:   89 e5                   mov    %esp,%ebp
  61:   83 ec 18                sub    $0x18,%esp
  64:   83 e4 f0                and    $0xfffffff0,%esp
  67:   b8 00 00 00 00          mov    $0x0,%eax
  6c:   29 c4                   sub    %eax,%esp
  6e:   a1 00 00 00 00          mov    0x0,%eax
  73:   89 45 e8                mov    %eax,0xffffffe8(%ebp)
  76:   6a 07                   push   $0x7
  78:   6a 06                   push   $0x6
  7a:   6a 05                   push   $0x5
  7c:   6a 04                   push   $0x4
  7e:   6a 03                   push   $0x3
  80:   6a 02                   push   $0x2
  82:   6a 01                   push   $0x1
  84:   6a 00                   push   $0x0
  86:   e8 fc ff ff ff          call   87 <main+0x29>
  8b:   83 c4 20                add    $0x20,%esp
  8e:   b8 00 00 00 00          mov    $0x0,%eax
  93:   8b 55 e8                mov    0xffffffe8(%ebp),%edx
  96:   3b 15 00 00 00 00       cmp    0x0,%edx
  9c:   74 13                   je     b1 <main+0x53>
  9e:   83 ec 08                sub    $0x8,%esp
  a1:   ff 75 e8                pushl  0xffffffe8(%ebp)
  a4:   68 0d 00 00 00          push   $0xd
  a9:   e8 fc ff ff ff          call   aa <main+0x4c>
  ae:   83 c4 10                add    $0x10,%esp
  b1:   c9                      leave
  b2:   c3                      ret



; output from godbolt compiler explorer w/ msvc 19.0

_leaf_call PROC
        push    ebp
        mov     ebp, esp
        pop     ebp
        ret     0
_leaf_call ENDP

_b$ = 12
_c$ = 16
_d$ = 20
_e$ = 24
_f$ = 28
_g$ = 32
_h$ = 36
_nonleaf_call PROC
        push    ebp
        mov     ebp, esp
        push    220
        call    _alloca
        add     esp, 4
        mov     BYTE PTR [eax], 76
        mov     eax, DWORD PTR _h$[ebp]
        push    eax
        mov     ecx, DWORD PTR _g$[ebp]
        push    ecx
        mov     edx, DWORD PTR _f$[ebp]
        push    edx
        mov     eax, DWORD PTR _e$[ebp]
        push    eax
        mov     ecx, DWORD PTR _d$[ebp]
        push    ecx
        mov     edx, DWORD PTR _c$[ebp]
        push    edx
        mov     eax, DWORD PTR _b$[ebp]
        push    eax
        call    _leaf_call
        add     esp, 28
        pop     ebp
        ret     0
_nonleaf_call ENDP

_main   PROC
        push    ebp
        mov     ebp, esp
        push    7
        push    6
        push    5
        push    4
        push    3
        push    2
        push    1
        push    0
        call    _nonleaf_call
        add     esp, 32
        xor     eax, eax
        pop     ebp
        ret     0
_main   ENDP



; ---------- structs by value, struct in first call on reg arg boundary ---------->
;
; struct A { int x; short y; char z; long long t; };
;
; struct A leaf_call(struct A a, short b, long long c, char d, int e, int f, int g, long long h)
; {
; 	a.x += 1;
; 	return a;
; }
;
; int main()
; {
; 	struct A a = {9, 99, 23, 12LL};
; 	leaf_call(a, 1, 2, 3, 4, 5, 6, 7LL);
; 	return 0;
; }



; output from godbolt compiler explorer w/ msvc 19.0

$T1 = 8
_a$ = 12
_leaf_call PROC
        push    ebp                        ; | prolog
        mov     ebp, esp                   ; /
        mov     eax, DWORD PTR _a$[ebp]    ; \
        add     eax, 1                     ; |  get struct's x (from stack args), add 1 and write back
        mov     DWORD PTR _a$[ebp], eax    ; /
        mov     ecx, DWORD PTR $T1[ebp]    ; get ptr to retval struct passed as hidden arg (+8 to skip retval and saved ebp)
        mov     edx, DWORD PTR _a$[ebp]    ; |
        mov     DWORD PTR [ecx], edx       ; |
        mov     eax, DWORD PTR _a$[ebp+4]  ; |
        mov     DWORD PTR [ecx+4], eax     ; | copy modified (b/c of x+=1) struct arg to space of retval
        mov     edx, DWORD PTR _a$[ebp+8]  ; |
        mov     DWORD PTR [ecx+8], edx     ; |
        mov     eax, DWORD PTR _a$[ebp+12] ; |
        mov     DWORD PTR [ecx+12], eax    ; |
        mov     eax, DWORD PTR $T1[ebp]    ; return value (= ptr to struct that was passed-in as hidden arg)
        pop     ebp                        ; |
        ret     0                          ; | epilog
_leaf_call ENDP

$T1 = -32
_a$ = -16
_main   PROC
        push    ebp                        ; |
        mov     ebp, esp                   ; | prolog
        sub     esp, 32                    ; /         32 = 16b local area for struct + 16b space used for retval struct
        mov     DWORD PTR _a$[ebp], 9      ; \                               int x
        mov     eax, 99                    ; |                               |
        mov     WORD PTR _a$[ebp+4], ax    ; | struct values (local area)    | short y
        mov     BYTE PTR _a$[ebp+6], 23    ; |                               char z
        mov     DWORD PTR _a$[ebp+8], 12   ; |                               |
        mov     DWORD PTR _a$[ebp+12], 0   ; /                               | long long t
        push    0                          ; \
        push    7                          ; | arg 7
        push    6                          ; arg 6
        push    5                          ; arg 5
        push    4                          ; arg 4
        push    3                          ; arg 3
        push    0                          ; |
        push    2                          ; arg 2
        push    1                          ; arg 1
        sub     esp, 16                    ; |
        mov     ecx, esp                   ; |
        mov     edx, DWORD PTR _a$[ebp]    ; |
        mov     DWORD PTR [ecx], edx       ; |
        mov     eax, DWORD PTR _a$[ebp+4]  ; |
        mov     DWORD PTR [ecx+4], eax     ; | arg 0 (struct), "pushed" onto stack (fetched from local area)
        mov     edx, DWORD PTR _a$[ebp+8]  ; |
        mov     DWORD PTR [ecx+8], edx     ; |
        mov     eax, DWORD PTR _a$[ebp+12] ; |
        mov     DWORD PTR [ecx+12], eax    ; /
        lea     ecx, DWORD PTR $T1[ebp]    ; \ ptr to space used for struct retval (pushed as hidden first arg)
        push    ecx                        ; |
        call    _leaf_call                 ; push return address and call
        add     esp, 56                    ; |
        xor     eax, eax                   ; : return value
        mov     esp, ebp                   ; |
        pop     ebp                        ; | epilog
        ret     0                          ; |
_main   ENDP



; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
;
; extern "C" {
; 
;     void f1(struct Trivial s)    { }
;     void f2(struct NonTrivial s) { }
;
;     void f()
;     {
;         struct Trivial t;
;         struct NonTrivial n;
;         int a=1;
;         a += 123;
;         f1(t);
;         a -= 123;
;         f2(n);
;         a -= 12;
;     }
; }



; output from openbsd-4.0-x86 w/ gcc 3.3.5 (propolice)

1c0005a0 <f1>:
1c0005a0:       55                      push   %ebp
1c0005a1:       89 e5                   mov    %esp,%ebp
1c0005a3:       c9                      leave
1c0005a4:       c3                      ret
1c0005a5:       90                      nop

1c0005a6 <f2>:
1c0005a6:       55                      push   %ebp
1c0005a7:       89 e5                   mov    %esp,%ebp
1c0005a9:       c9                      leave
1c0005aa:       c3                      ret
1c0005ab:       90                      nop

1c0005ac <f>:
1c0005ac:       55                      push   %ebp                              ;
1c0005ad:       89 e5                   mov    %esp,%ebp                         ;
1c0005af:       83 ec 48                sub    $0x48,%esp                        ;
1c0005b2:       83 ec 0c                sub    $0xc,%esp                         ;
1c0005b5:       8d 45 d8                lea    0xffffffd8(%ebp),%eax             ;

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

1c000939:       8b 5d 08                mov    0x8(%ebp),%ebx
1c00093c:       83 ec 0c                sub    $0xc,%esp
1c00093f:       53                      push   %ebx
1c000940:       e8 87 00 00 00          call   1c0009cc <_ZN10NonTrivialC1Ev>
1c000945:       83 c4 10                add    $0x10,%esp
1c000948:       89 d8                   mov    %ebx,%eax
1c00094a:       8b 5d fc                mov    0xfffffffc(%ebp),%ebx
1c00094d:       c9                      leave
1c00094e:       c2 04 00                ret    $0x4
1c000951:       90                      nop

1c000952 <f>:
1c000952:       55                      push   %ebp                  ;
1c000953:       89 e5                   mov    %esp,%ebp             ;
1c000955:       83 ec 28                sub    $0x28,%esp            ;
1c000958:       c7 45 f4 01 00 00 00    movl   $0x1,0xfffffff4(%ebp) ; a = 1
1c00095f:       8d 45 f4                lea    0xfffffff4(%ebp),%eax ; |
1c000962:       83 00 7b                addl   $0x7b,(%eax)          ; | a += 12
1c000965:       e8 b6 ff ff ff          call   1c000920 <f1>         ; call f1()
1c00096a:       89 45 f0                mov    %eax,0xfffffff0(%ebp) ; retval (trivial struct <= 32bits, returned via eax)
1c00096d:       8d 45 f4                lea    0xfffffff4(%ebp),%eax ; |
1c000970:       83 28 7b                subl   $0x7b,(%eax)          ; | a -= 123
1c000973:       8d 45 d8                lea    0xffffffd8(%ebp),%eax ; space (at top of stack) to hold non-triv retval -> eax
1c000976:       83 ec 0c                sub    $0xc,%esp             ; grow stack by 12
1c000979:       50                      push   %eax                  ; hidden first arg: ptr to space for retval
1c00097a:       e8 b3 ff ff ff          call   1c000932 <_Z2f2v>     ; call f2()
1c00097f:       83 c4 0c                add    $0xc,%esp             ; shrink stack back by 12
1c000982:       8d 45 f4                lea    0xfffffff4(%ebp),%eax ; |
1c000985:       83 28 0c                subl   $0xc,(%eax)           ; | a -= 12
1c000988:       c9                      leave                        ;
1c000989:       c3                      ret                          ;



; ---------- cdecl-declared (explicit) C++ thiscall w/ msvc ---------->
;
; class C {
; public:
;     float __cdecl m(int i) const { return float(i + 123); }
; };
;
; extern "C" {
;     float f()
;     {
;         C c;
;         return c.m(27);
;     }
; }



; output from godbolt compiler explorer w/ msvc 19.0

tv68 = -8
tv67 = -4
_i$ = 12
float C::m(int)const  PROC
        push    ebp                      ;
        mov     ebp, esp                 ;
        sub     esp, 8                   ;
        mov     eax, DWORD PTR _i$[ebp]  ;
        add     eax, 123                 ; |
        mov     DWORD PTR tv67[ebp], eax ; / in arg + 123, pushed onto stack
        fild    DWORD PTR tv67[ebp]      ; \
        fstp    DWORD PTR tv68[ebp]      ; | float cast and put return value in fp0
        fld     DWORD PTR tv68[ebp]      ; |
        mov     esp, ebp                 ;
        pop     ebp                      ;
        ret     0                        ;
float C::m(int)const  ENDP

_c$ = -1
_f      PROC                             ;
        push    ebp                      ;
        mov     ebp, esp                 ;
        push    ecx                      ;
        push    27                       ; arg 1
        lea     eax, DWORD PTR _c$[ebp]  ; |
        push    eax                      ; | arg 0 (this ptr)
        call    float C::m(int)const     ; call C::m()
        add     esp, 8                   ;
        mov     esp, ebp                 ;
        pop     ebp                      ;
        ret     0                        ;
_f      ENDP



; vim: ft=asm



( run in 1.864 second using v1.01-cache-2.11-cpan-aadc1410aed )