Mercurial > pub > dyncall > dyncall
diff 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 |
line wrap: on
line diff
--- a/doc/disas_examples/x86.fastcall_ms.disas Thu Apr 14 21:18:02 2022 +0200 +++ b/doc/disas_examples/x86.fastcall_ms.disas Sat Apr 16 12:10:02 2022 +0200 @@ -184,5 +184,221 @@ +; ---------- 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 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 + ret 4 +@f1@4 ENDP + +_s$ = 8 +@f2@4 PROC + push ebp + mov ebp, esp + pop ebp + 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; }; +; struct NonTrivial { +; int a; +; NonTrivial() : a(0) {} +; NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } +; }; +; +; extern "C" { +; struct Trivial f1() { return Trivial(); } +; } +; +; struct NonTrivial f2() { return NonTrivial(); } +; +; extern "C" { +; void f() +; { +; int a=1; +; a += 123; +; struct Trivial t = f1(); +; a -= 123; +; struct NonTrivial n = f2(); +; a -= 12; +; } +; } + + + +; 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 + xor eax, eax + mov DWORD PTR $T1[ebp], eax + mov eax, DWORD PTR $T1[ebp] + 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