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,