3.18. C++
Listing 3.84: MSVC
??0c@@QAE@XZ PROC ; c::c, COMDAT
; _this$ = ecx
mov eax, ecx
mov DWORD PTR [eax], 667
mov DWORD PTR [eax+4], 999
ret 0
??0c@@QAE@XZ ENDP ; c::c
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
??0c@@QAE@HH@Z PROC ; c::c, COMDAT
; _this$ = ecx
mov edx, DWORD PTR _b$[esp-4]
mov eax, ecx
mov ecx, DWORD PTR _a$[esp-4]
mov DWORD PTR [eax], ecx
mov DWORD PTR [eax+4], edx
ret 8
??0c@@QAE@HH@Z ENDP ; c::c
?dump@c@@QAEXXZ PROC ; c::dump, COMDAT
; _this$ = ecx
mov eax, DWORD PTR [ecx+4]
mov ecx, DWORD PTR [ecx]
push eax
push ecx
push OFFSET ??_C@_07NJBDCIEC@?$CFd?$DL?5?$CFd?6?$AA@
call _printf
add esp, 12
ret 0
?dump@c@@QAEXXZ ENDP ; c::dump
That’s all. The other thing we must note is that thestack pointerhasn’t been corrected withadd esp, X
after the constructor has been called. At the same time, the constructor hasret 8instead ofRETat the
end.
This is all because the thiscall (3.18.1 on page 542) calling convention is used here, which together with
the stdcall (6.1.2 on page 734) method offers thecalleeto correct the stack instead of thecaller. The
ret xinstruction addsXto the value inESP, then passes the control to thecallerfunction.
See also the section about calling conventions (6.1 on page 734).
It also has to be noted that the compiler decides when to call the constructor and destructor—but we
already know that from the C++ language basics.
MSVC: x86-64
As we already know, the first 4 function arguments in x86-64 are passed inRCX,RDX,R8andR9registers,
all the rest—via the stack.
Nevertheless, thethispointer to the object is passed inRCX, the first argument of the method inRDX, etc.
We can see this in thec(int a, int b)method internals:
Listing 3.85: Optimizing MSVC 2012 x64
; void dump()
?dump@c@@QEAAXXZ PROC ; c::dump
mov r8d, DWORD PTR [rcx+4]
mov edx, DWORD PTR [rcx]
lea rcx, OFFSET FLAT:??_C@_07NJBDCIEC@?$CFd?$DL?5?$CFd?6?$AA@ ; '%d; %d'
jmp printf
?dump@c@@QEAAXXZ ENDP ; c::dump
; c(int a, int b)
??0c@@QEAA@HH@Z PROC ; c::c
mov DWORD PTR [rcx], edx ; 1st argument: a