Affix

 view release on metacpan or  search on metacpan

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

f$ = 136
g$ = 144
h$ = 152
nonleaf_call PROC
        mov     DWORD PTR [rsp+32], r9d   ; | |
        mov     DWORD PTR [rsp+24], r8d   ; | |
        mov     DWORD PTR [rsp+16], edx   ; | | spill
        mov     DWORD PTR [rsp+8], ecx    ; | |
        push    rdi                       ; |
        sub     rsp, 80                   ; | prolog
        mov     BYTE PTR x$[rsp], 76      ; 'L' -> local area (of local array's space)
        lea     rax, QWORD PTR x$[rsp+1]  ; |
        mov     rdi, rax                  ; |
        xor     eax, eax                  ; | zero-init rest of local array's space
        mov     ecx, 9                    ; |
        rep stosb                         ; |
        mov     eax, DWORD PTR h$[rsp]    ; arg 6 (fetched from caller's frame param area), and ...
        mov     DWORD PTR [rsp+48], eax   ; ... "pushed" onto stack
        mov     eax, DWORD PTR g$[rsp]    ; arg 5 (fetched from caller's frame param area), and ...
        mov     DWORD PTR [rsp+40], eax   ; ... "pushed" onto stack
        mov     eax, DWORD PTR f$[rsp]    ; arg 4 (fetched from caller's frame param area), and ...
        mov     DWORD PTR [rsp+32], eax   ; ... "pushed" onto stack
        mov     r9d, DWORD PTR e$[rsp]    ; arg 3
        mov     r8d, DWORD PTR d$[rsp]    ; arg 2
        mov     edx, DWORD PTR c$[rsp]    ; arg 1
        mov     ecx, DWORD PTR b$[rsp]    ; arg 0
        call    leaf_call                 ; push return addr and call
        add     rsp, 80                   ; |
        pop     rdi                       ; | epilog
        ret     0                         ; |
nonleaf_call ENDP

main    PROC
        sub     rsp, 72                   ; prolog
        mov     DWORD PTR [rsp+56], 7     ; "push" arg 7 onto stack
        mov     DWORD PTR [rsp+48], 6     ; "push" arg 6 onto stack

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

g$ = 384
h$ = 392
nonleaf_call PROC
        mov     DWORD PTR [rsp+32], r9d
        mov     DWORD PTR [rsp+24], r8d
        mov     DWORD PTR [rsp+16], edx
        mov     DWORD PTR [rsp+8], ecx
        push    rsi
        push    rdi
        sub     rsp, 312
        mov     BYTE PTR x$[rsp], 76
        lea     rax, QWORD PTR x$[rsp+1]
        mov     rdi, rax
        xor     eax, eax
        mov     ecx, 219
        rep stosb
        lea     rax, QWORD PTR $T1[rsp]
        mov     rdi, rax
        mov     rsi, QWORD PTR f$[rsp]
        mov     ecx, 16
        rep movsb
        mov     eax, DWORD PTR h$[rsp]
        mov     DWORD PTR [rsp+48], eax
        mov     eax, DWORD PTR g$[rsp]
        mov     DWORD PTR [rsp+40], eax
        lea     rax, QWORD PTR $T1[rsp]
        mov     QWORD PTR [rsp+32], rax
        mov     r9d, DWORD PTR e$[rsp]
        mov     r8d, DWORD PTR d$[rsp]
        mov     edx, DWORD PTR c$[rsp]
        mov     ecx, DWORD PTR b$[rsp]
        call    leaf_call
        add     rsp, 312
        pop     rdi
        pop     rsi
        ret     0
nonleaf_call ENDP

a$ = 64
$T1 = 80
main    PROC
        push    rsi
        push    rdi
        sub     rsp, 104
        mov     DWORD PTR a$[rsp], 5
        mov     DWORD PTR a$[rsp+4], 6
        mov     QWORD PTR a$[rsp+8], 7
        lea     rax, QWORD PTR $T1[rsp]
        lea     rcx, QWORD PTR a$[rsp]
        mov     rdi, rax
        mov     rsi, rcx
        mov     ecx, 16
        rep movsb
        mov     DWORD PTR [rsp+56], 9
        mov     DWORD PTR [rsp+48], 8
        lea     rax, QWORD PTR $T1[rsp]
        mov     QWORD PTR [rsp+40], rax
        mov     DWORD PTR [rsp+32], 4
        mov     r9d, 3

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

i$ = 464
j$ = 472
nonleaf_call PROC
        mov     QWORD PTR [rsp+32], r9
        mov     QWORD PTR [rsp+24], r8
        mov     DWORD PTR [rsp+16], edx
        mov     DWORD PTR [rsp+8], ecx
        push    rsi
        push    rdi
        sub     rsp, 376
        mov     BYTE PTR x$[rsp], 76
        lea     rax, QWORD PTR x$[rsp+1]
        mov     rdi, rax
        xor     eax, eax
        mov     ecx, 219
        rep stosb
        lea     rax, QWORD PTR $T3[rsp]
        mov     rdi, rax
        mov     rsi, QWORD PTR h$[rsp]
        mov     ecx, 16
        rep movsb
        lea     rax, QWORD PTR $T1[rsp]
        mov     rdi, rax
        mov     rsi, QWORD PTR g$[rsp]
        mov     ecx, 12
        rep movsb
        lea     rax, QWORD PTR $T4[rsp]
        mov     rdi, rax
        mov     rsi, QWORD PTR d$[rsp]
        mov     ecx, 16
        rep movsb
        lea     rax, QWORD PTR $T2[rsp]
        mov     rdi, rax
        mov     rsi, QWORD PTR c$[rsp]
        mov     ecx, 12
        rep movsb
        mov     eax, DWORD PTR j$[rsp]
        mov     DWORD PTR [rsp+64], eax
        mov     eax, DWORD PTR i$[rsp]
        mov     DWORD PTR [rsp+56], eax
        lea     rax, QWORD PTR $T3[rsp]
        mov     QWORD PTR [rsp+48], rax
        lea     rax, QWORD PTR $T1[rsp]
        mov     QWORD PTR [rsp+40], rax
        mov     eax, DWORD PTR f$[rsp]
        mov     DWORD PTR [rsp+32], eax
        mov     r9d, DWORD PTR e$[rsp]
        lea     r8, QWORD PTR $T4[rsp]
        lea     rdx, QWORD PTR $T2[rsp]
        mov     ecx, DWORD PTR b$[rsp]
        call    leaf_call
        add     rsp, 376
        pop     rdi
        pop     rsi
        ret     0
nonleaf_call ENDP

c$ = 80
a$ = 96
$T1 = 112
$T2 = 128
d$ = 144
b$ = 160
$T3 = 176
$T4 = 192
main    PROC
        push    rsi
        push    rdi
        sub     rsp, 216
        mov     DWORD PTR a$[rsp], 2
        mov     DWORD PTR a$[rsp+4], 3
        movss   xmm0, DWORD PTR __real@40800000
        movss   DWORD PTR a$[rsp+8], xmm0
        movsd   xmm0, QWORD PTR __real@4014000000000000
        movsd   QWORD PTR b$[rsp], xmm0
        mov     QWORD PTR b$[rsp+8], 6
        mov     DWORD PTR c$[rsp], 9
        mov     DWORD PTR c$[rsp+4], 10
        movss   xmm0, DWORD PTR __real@41300000
        movss   DWORD PTR c$[rsp+8], xmm0
        movsd   xmm0, QWORD PTR __real@4028000000000000
        movsd   QWORD PTR d$[rsp], xmm0
        mov     QWORD PTR d$[rsp+8], 13
        lea     rax, QWORD PTR $T3[rsp]
        lea     rcx, QWORD PTR d$[rsp]
        mov     rdi, rax
        mov     rsi, rcx
        mov     ecx, 16
        rep movsb
        lea     rax, QWORD PTR $T1[rsp]
        lea     rcx, QWORD PTR c$[rsp]
        mov     rdi, rax
        mov     rsi, rcx
        mov     ecx, 12
        rep movsb
        lea     rax, QWORD PTR $T4[rsp]
        lea     rcx, QWORD PTR b$[rsp]
        mov     rdi, rax
        mov     rsi, rcx
        mov     ecx, 16
        rep movsb
        lea     rax, QWORD PTR $T2[rsp]
        lea     rcx, QWORD PTR a$[rsp]
        mov     rdi, rax
        mov     rsi, rcx
        mov     ecx, 12
        rep movsb
        mov     DWORD PTR [rsp+72], 15
        mov     DWORD PTR [rsp+64], 14
        lea     rax, QWORD PTR $T3[rsp]
        mov     QWORD PTR [rsp+56], rax
        lea     rax, QWORD PTR $T1[rsp]
        mov     QWORD PTR [rsp+48], rax

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN




; output from godbolt compiler explorer w/ msvc 19.0

r$ = 0
c$ = 32
call    PROC
        mov     BYTE PTR [rsp+8], cl   ; |         spill
        sub     rsp, 24                ; | prolog
        movzx   eax, BYTE PTR c$[rsp]  ; in arg 0 (fetched from spill area) -> eax, then ...
        mov     BYTE PTR r$[rsp], al   ; ... -> struct in local area (top of stack, as leaf call and thus no reserved spill area)
        movzx   eax, BYTE PTR r$[rsp]  ; reget same value into eax to return (small) struct via reg (a bit pointless to refetch)
        add     rsp, 24                ; |
        ret     0                      ; | epilog
call    ENDP

a$ = 32
main    PROC
        sub     rsp, 56                ; prolog
        mov     cl, 123                ; arg 0
        call    call                   ; push return addr and call
        mov     BYTE PTR a$[rsp], al   ; write struct data to local area (123)
        xor     eax, eax               ; return value
        add     rsp, 56                ; |
        ret     0                      ; | epilog
main    ENDP



; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
;
; struct Trivial { int a; };

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

f2      ENDP

a$ = 32
n$ = 36
t$ = 40
$T1 = 44
$T2 = 48
f       PROC
$LN3:
        sub     rsp, 72                                    ; prolog
        lea     rcx, QWORD PTR n$[rsp]                     ; \ this ptr (NULL)
        call    NonTrivial::NonTrivial(void)               ; | NonTrivial::NonTrivial() / ctor
        mov     DWORD PTR a$[rsp], 1                       ; a = 1
        mov     eax, DWORD PTR a$[rsp]                     ; |
        add     eax, 123                                   ; | a += 123
        mov     DWORD PTR a$[rsp], eax                     ; /
        mov     ecx, DWORD PTR t$[rsp]                     ; f1 arg 0 (struct Trivial), via reg as small struct
        call    f1                                         ; call f1(struct Trivial)
        mov     eax, DWORD PTR a$[rsp]                     ; |
        sub     eax, 123                                   ; | a -= 123
        mov     DWORD PTR a$[rsp], eax                     ; /
        lea     rax, QWORD PTR $T1[rsp]                    ; @@@ unsure
        mov     QWORD PTR $T2[rsp], rax                    ; ... @@@
        lea     rdx, QWORD PTR n$[rsp]                     ; \               ptr to dest of copy of n
        mov     rcx, QWORD PTR $T2[rsp]                    ; | copy n        ptr to n
        call    NonTrivial::NonTrivial(NonTrivial const &) ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
        mov     rcx, rax                                   ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
        call    f2                                         ; call f2(struct NonTrivial)
        mov     eax, DWORD PTR a$[rsp]                     ; |
        sub     eax, 12                                    ; | a -= 12
        mov     DWORD PTR a$[rsp], eax                     ; /
        add     rsp, 72                                    ; \
        ret     0                                          ; | epilog
f       ENDP



; ---------- C++ trivial and non-trivial aggrs as return values ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

        add     rsp, 16
        pop     rdi
        ret     0
f1      ENDP

__$ReturnUdt$ = 48
NonTrivial f2(void) PROC
$LN3:
        mov     QWORD PTR [rsp+8], rcx
        sub     rsp, 40
        mov     rcx, QWORD PTR __$ReturnUdt$[rsp]
        call    NonTrivial::NonTrivial(void)
        mov     rax, QWORD PTR __$ReturnUdt$[rsp]
        add     rsp, 40
        ret     0
NonTrivial f2(void) ENDP

a$ = 32
$T1 = 36
t$ = 40
n$ = 44
f       PROC
$LN3:
        sub     rsp, 56                 ; prolog
        mov     DWORD PTR a$[rsp], 1    ; a = 1
        mov     eax, DWORD PTR a$[rsp]  ; |
        add     eax, 123                ; | a += 123
        mov     DWORD PTR a$[rsp], eax  ; |
        call    f1                      ; call f1()
        mov     DWORD PTR $T1[rsp], eax ;
        mov     eax, DWORD PTR $T1[rsp] ;
        mov     DWORD PTR t$[rsp], eax  ;
        mov     eax, DWORD PTR a$[rsp]  ; |
        sub     eax, 123                ; | a -= 123
        mov     DWORD PTR a$[rsp], eax  ; |
        lea     rcx, QWORD PTR n$[rsp]  ; ptr to space to hold non-triv retval
        call    NonTrivial f2(void)     ; call f2()
        mov     eax, DWORD PTR a$[rsp]  ; |
        sub     eax, 12                 ; | a -= 12
        mov     DWORD PTR a$[rsp], eax  ; /
        add     rsp, 56                 ; \ epilog
        ret     0                       ; |
f       ENDP                             



; ---------- structs by value, struct passed as vararg ---------->
;
; #include <stdlib.h>
; #include <stdarg.h>

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

$LN3:
        mov     DWORD PTR [rsp+24], r8d          ;
        mov     DWORD PTR [rsp+16], edx          ;
        mov     DWORD PTR [rsp+8], ecx           ;
        mov     QWORD PTR [rsp+32], r9           ;
        push    rsi                              ;
        push    rdi                              ;
        sub     rsp, 152                         ;
        mov     rax, QWORD PTR __security_cookie ;
        xor     rax, rsp                         ;
        mov     QWORD PTR __$ArrayPad$[rsp], rax ;
        lea     rax, QWORD PTR c$[rsp+8]         ;
        mov     QWORD PTR ap$[rsp], rax          ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        add     rax, 8                           ;
        mov     QWORD PTR ap$[rsp], rax          ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        mov     eax, DWORD PTR [rax-8]           ;
        mov     DWORD PTR d$[rsp], eax           ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        add     rax, 8                           ;
        mov     QWORD PTR ap$[rsp], rax          ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        mov     eax, DWORD PTR [rax-8]           ;
        mov     DWORD PTR e$[rsp], eax           ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        add     rax, 8                           ;
        mov     QWORD PTR ap$[rsp], rax          ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        mov     rax, QWORD PTR [rax-8]           ;
        lea     rcx, QWORD PTR f$[rsp]           ;
        mov     rdi, rcx                         ;
        mov     rsi, rax                         ;
        mov     ecx, 16                          ;
        rep movsb                                ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        add     rax, 8                           ;
        mov     QWORD PTR ap$[rsp], rax          ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        mov     eax, DWORD PTR [rax-8]           ;
        mov     DWORD PTR g$[rsp], eax           ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        add     rax, 8                           ;
        mov     QWORD PTR ap$[rsp], rax          ;
        mov     rax, QWORD PTR ap$[rsp]          ;
        mov     eax, DWORD PTR [rax-8]           ;
        mov     DWORD PTR h$[rsp], eax           ;
        mov     ecx, 220                         ;
        call    alloca                           ;
        cdqe                                     ;
        mov     BYTE PTR [rax], 76               ;
        lea     rax, QWORD PTR $T1[rsp]          ;
        lea     rcx, QWORD PTR f$[rsp]           ;
        mov     rdi, rax                         ;
        mov     rsi, rcx                         ;
        mov     ecx, 16                          ;
        rep movsb                                ;
        mov     eax, DWORD PTR h$[rsp]           ;
        mov     DWORD PTR [rsp+48], eax          ;
        mov     eax, DWORD PTR g$[rsp]           ;
        mov     DWORD PTR [rsp+40], eax          ;
        lea     rax, QWORD PTR $T1[rsp]          ;
        mov     QWORD PTR [rsp+32], rax          ;
        mov     r9d, DWORD PTR e$[rsp]           ;
        mov     r8d, DWORD PTR d$[rsp]           ;
        mov     edx, DWORD PTR c$[rsp]           ;
        mov     ecx, DWORD PTR b$[rsp]           ;
        call    leaf_call                        ;
        mov     QWORD PTR ap$[rsp], 0            ;
        mov     rcx, QWORD PTR __$ArrayPad$[rsp] ;
        xor     rcx, rsp                         ;
        call    __security_check_cookie          ;
        add     rsp, 152                         ;
        pop     rdi                              ;
        pop     rsi                              ;
        ret     0                                ;
nonleaf_call ENDP

$T1 = 64
$S1$ = 80
__$ArrayPad$ = 96
main    PROC
$LN3:
        push    rsi                              ;
        push    rdi                              ;
        sub     rsp, 120                         ;
        mov     rax, QWORD PTR __security_cookie ;
        xor     rax, rsp                         ;
        mov     QWORD PTR __$ArrayPad$[rsp], rax ;
        mov     DWORD PTR $S1$[rsp], 5           ;
        mov     DWORD PTR $S1$[rsp+4], 6         ;
        mov     QWORD PTR $S1$[rsp+8], 7         ;
        lea     rax, QWORD PTR $T1[rsp]          ;
        lea     rcx, QWORD PTR $S1$[rsp]         ;
        mov     rdi, rax                         ;
        mov     rsi, rcx                         ;
        mov     ecx, 16                          ;
        rep movsb                                ;
        mov     DWORD PTR [rsp+56], 9            ;
        mov     DWORD PTR [rsp+48], 8            ;
        lea     rax, QWORD PTR $T1[rsp]          ;
        mov     QWORD PTR [rsp+40], rax          ;
        mov     DWORD PTR [rsp+32], 4            ;
        mov     r9d, 3                           ;
        mov     r8d, 2                           ;
        mov     edx, 1                           ;
        xor     ecx, ecx                         ;
        call    nonleaf_call                     ;
        xor     eax, eax                         ;
        mov     rcx, QWORD PTR __$ArrayPad$[rsp] ;
        xor     rcx, rsp                         ;
        call    __security_check_cookie          ;
        add     rsp, 120                         ;
        pop     rdi                              ;
        pop     rsi                              ;
        ret     0                                ;
main    ENDP



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

_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

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




; 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

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


; 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



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



; output from godbolt compiler explorer w/ msvc 19.0 (/Gr for fastcall)

_b$ = -8
_c$ = -4
@leaf_call@28 PROC
        push    ebp
        mov     ebp, esp
        sub     esp, 8
        mov     DWORD PTR _c$[ebp], edx
        mov     DWORD PTR _b$[ebp], ecx
        mov     esp, ebp
        pop     ebp
        ret     20
@leaf_call@28 ENDP

_a$ = -8
_b$ = -4
_c$ = 8
_d$ = 12
_e$ = 16
_f$ = 20
_g$ = 24
_h$ = 28
@nonleaf_call@32 PROC
        push    ebp                      ; |
        mov     ebp, esp                 ; | prolog
        sub     esp, 8                   ; |
        mov     DWORD PTR _b$[ebp], edx  ; in arg 1 -> local area on stack
        mov     DWORD PTR _a$[ebp], ecx  ; in arg 0 -> local area on stack
        mov     ecx, 220                 ; |
        call    @alloca@4                ; | call alloca(220)   (ecx = arg)
        mov     BYTE PTR [eax], 76       ; 'L' -> alloca()'d space (pointed to by alloca's retval in eax)
        mov     eax, DWORD PTR _h$[ebp]  ; |
        push    eax                      ; |
        mov     ecx, DWORD PTR _g$[ebp]  ; |
        push    ecx                      ; |
        mov     edx, DWORD PTR _f$[ebp]  ; | read in args 3-7 from prev frame's param area, and ...
        push    edx                      ; | ... "push" onto stack as arg 2-6
        mov     eax, DWORD PTR _e$[ebp]  ; |
        push    eax                      ; |
        mov     ecx, DWORD PTR _d$[ebp]  ; |
        push    ecx                      ; |
        mov     edx, DWORD PTR _c$[ebp]  ; arg 1        | read from prev frame's param
        mov     ecx, DWORD PTR _b$[ebp]  ; arg 0        | area and put in regs
        call    @leaf_call@28            ; push return address and call
        mov     esp, ebp                 ; |
        pop     ebp                      ; | epilog
        ret     24                       ; |
@nonleaf_call@32 ENDP

_main   PROC
        push    ebp                      ; | prolog
        mov     ebp, esp                 ; |
        push    7                        ; arg 7

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

_a$ = 12
_c$ = 28
_e$ = 36
_f$ = 40
_g$ = 44
_h$ = 48
@leaf_call@52 PROC
        push    ebp                        ; |
        mov     ebp, esp                   ; | prolog
        sub     esp, 8                     ; |
        mov     BYTE PTR _d$[ebp], dl      ; in arg 3 -> local area on stack
        mov     WORD PTR _b$[ebp], cx      ; in arg 1 -> local area on stack
        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)
        mov     esp, ebp                   ; |
        pop     ebp                        ; | epilog
        ret     48                         ; |
@leaf_call@52 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    0                          ; |
        push    2                          ; / arg 2 (via stack b/c not first arg and > 32 bits)
        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                        ; |
        mov     dl, 3                      ; arg 3 (via reg)
        mov     ecx, 1                     ; arg 1 (via reg)
        call    @leaf_call@52              ; push return address and call
        xor     eax, eax                   ; return value
        mov     esp, ebp                   ; |
        pop     ebp                        ; | epilog
        ret     0                          ; |

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




; output from godbolt compiler explorer w/ msvc 19.31 (/Gr for fastcall)

_this$ = -4
NonTrivial::NonTrivial(void) PROC
        push    ebp
        mov     ebp, esp
        push    ecx
        mov     DWORD PTR _this$[ebp], ecx
        mov     eax, DWORD PTR _this$[ebp]
        mov     DWORD PTR [eax], 0
        mov     eax, DWORD PTR _this$[ebp]
        mov     esp, ebp
        pop     ebp
        ret     0
NonTrivial::NonTrivial(void) ENDP

_this$ = -4
_rhs$ = 8
NonTrivial::NonTrivial(NonTrivial const &) PROC
        push    ebp
        mov     ebp, esp
        push    ecx
        mov     DWORD PTR _this$[ebp], ecx
        mov     eax, DWORD PTR _this$[ebp]
        mov     ecx, DWORD PTR _rhs$[ebp]
        mov     edx, DWORD PTR [ecx]
        mov     DWORD PTR [eax], edx
        mov     eax, DWORD PTR _this$[ebp]
        mov     esp, ebp
        pop     ebp
        ret     4
NonTrivial::NonTrivial(NonTrivial const &) ENDP

_s$ = 8
@f1@4   PROC
        push    ebp
        mov     ebp, esp
        pop     ebp

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

        ret     4
@f2@4   ENDP

_t$ = -12
_n$ = -8
_a$ = -4
@f@0    PROC
        push    ebp                                        ;
        mov     ebp, esp                                   ;
        sub     esp, 12                                    ;
        lea     ecx, DWORD PTR _n$[ebp]                    ;
        call    NonTrivial::NonTrivial(void)               ;
        mov     DWORD PTR _a$[ebp], 1                      ;
        mov     eax, DWORD PTR _a$[ebp]                    ;
        add     eax, 123                                   ;
        mov     DWORD PTR _a$[ebp], eax                    ;
        mov     ecx, DWORD PTR _t$[ebp]                    ;
        push    ecx                                        ;
        call    @f1@4                                      ;
        mov     edx, DWORD PTR _a$[ebp]                    ;
        sub     edx, 123                                   ;
        mov     DWORD PTR _a$[ebp], edx                    ;
        push    ecx                                        ;
        mov     ecx, esp                                   ;
        lea     eax, DWORD PTR _n$[ebp]                    ;
        push    eax                                        ;
        call    NonTrivial::NonTrivial(NonTrivial const &) ;
        call    @f2@4                                      ;
        mov     ecx, DWORD PTR _a$[ebp]                    ;
        sub     ecx, 12                                    ;
        mov     DWORD PTR _a$[ebp], ecx                    ;
        mov     esp, ebp                                   ;
        pop     ebp                                        ;
        ret     0                                          ;
@f@0    ENDP



; ---------- C++ trivial and non-trivial aggrs as return values ---------->
;
; struct Trivial { int a; };

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




; output from godbolt compiler explorer w/ msvc 19.31 (/Gr for fastcall)

_this$ = -4
NonTrivial::NonTrivial(void) PROC
        push    ebp
        mov     ebp, esp
        push    ecx
        mov     DWORD PTR _this$[ebp], ecx
        mov     eax, DWORD PTR _this$[ebp]
        mov     DWORD PTR [eax], 0
        mov     eax, DWORD PTR _this$[ebp]
        mov     esp, ebp
        pop     ebp
        ret     0
NonTrivial::NonTrivial(void) ENDP

$T1 = -4
@f1@0   PROC
        push    ebp
        mov     ebp, esp
        push    ecx

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

        mov     esp, ebp
        pop     ebp
        ret     0
@f1@0   ENDP

___$ReturnUdt$ = -4
NonTrivial f2(void) PROC
        push    ebp                                ;
        mov     ebp, esp                           ;
        push    ecx                                ; ptr to hidden retval space as first arg (fastcall, in ecx)
        mov     DWORD PTR ___$ReturnUdt$[ebp], ecx ; |
        mov     ecx, DWORD PTR ___$ReturnUdt$[ebp] ; | a bit pointless
        call    NonTrivial::NonTrivial(void)       ;
        mov     eax, DWORD PTR ___$ReturnUdt$[ebp] ; return passed-in ptr ptr to hidden retval space in eax
        mov     esp, ebp                           ;
        pop     ebp                                ;
        ret     0                                  ;
NonTrivial f2(void) ENDP

_n$ = -16
_t$ = -12
$T1 = -8
_a$ = -4
@f@0    PROC
        push    ebp                     ;
        mov     ebp, esp                ;
        sub     esp, 16                 ;
        mov     DWORD PTR _a$[ebp], 1   ; a = 1
        mov     eax, DWORD PTR _a$[ebp] ; |
        add     eax, 123                ; | a += 123
        mov     DWORD PTR _a$[ebp], eax ; |
        call    @f1@0                   ; call f1()
        mov     DWORD PTR $T1[ebp], eax ; retval (trivial struct <= 32bits, returned via eax)
        mov     ecx, DWORD PTR $T1[ebp] ; | copy of retval from stack to stack
        mov     DWORD PTR _t$[ebp], ecx ; /
        mov     edx, DWORD PTR _a$[ebp] ; \
        sub     edx, 123                ; | a -= 123
        mov     DWORD PTR _a$[ebp], edx ; |
        lea     ecx, DWORD PTR _n$[ebp] ; hidden first arg: ptr to space for (non-trivial) retval
        call    NonTrivial f2(void)     ; call f2()
        mov     eax, DWORD PTR _a$[ebp] ; |
        sub     eax, 12                 ; | a -= 12
        mov     DWORD PTR _a$[ebp], eax ; |
        mov     esp, ebp                ;
        pop     ebp                     ;
        ret     0                       ;
@f@0    ENDP



; vim: ft=asm

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

_f$ = 28
_g$ = 32
_h$ = 36
_nonleaf_call@32 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@28
        pop     ebp
        ret     32
_nonleaf_call@32 ENDP

_main   PROC
        push    ebp
        mov     ebp, esp
        push    7

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




; output from godbolt compiler explorer w/ msvc 19.14 (w/ /GS- for simplicity)

$T1 = 8
_a$ = 12
_leaf_call@52 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     56                         ; | epilog (56 = stack cleanup of stdcall)
_leaf_call@52 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@52              ; push return address and call
                                           ; (note: cdecl would clean up stack, here)
        xor     eax, eax                   ; return value
        mov     esp, ebp                   ; |
        pop     ebp                        ; | epilog
        ret     0                          ; |
_main   ENDP

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

; output from godbolt compiler explorer w/ msvc 19.0

_this$ = -12
tv68 = -8
tv67 = -4
_i$ = 8
float C::m(int)const  PROC
        push    ebp                        ;
        mov     ebp, esp                   ;
        sub     esp, 12                    ;
        mov     DWORD PTR _this$[ebp], ecx ;
        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     4                          ;
float C::m(int)const  ENDP

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



; output from reactos-0.3.15-x86 w/ mingw gcc 4.7.2 (uses MS thiscalls; according to
; https://www.angelcode.com/dev/callconv/callconv.html MinGW has own thiscalls,



( run in 1.775 second using v1.01-cache-2.11-cpan-b61123c0432 )