c++ Constructor Calling convention
-
hi ich hab da mal ne frage, also mein problem ist folgendes, ich möcht von inline _asm aus C++ funktionen, aufrufen von denen ich die adresse habe, bei __thisscall, oder stdcall funktioniert das auchschon ganz gut, da kenne ihc ja die caling convention
(für thiscall z.b. alle argumente auf dem stack, der thispointer im ecx register...)
aber leider weiss ich nicht, was für eine calling convention Konstruktoren in Visual c++ übliocherweise haben :(, also weiss ich nicht wie ich die argumente an die funktion (den kostruktor) übergeben soll, bzw wie wo ich den rückgabewert finde.kann mir da vieleicht jmd hier helfen?
-
Das kommt auf deine Compilereinstellung an.
Wenn Du VC2008 benutzt wird die std einstellung wohl __cdecl sein,..
Ansonsten einfach mal ne klasse basteln und zwo verschiedene words übergeben und mit nem disasm anschauen,...grüüße
-
Konstruktoren sind aber allerdings ziemlich oft inlined da sie selten sonderlich komplex sind.
-
danke erstmal für diese informationen,
habe jetzt aber gelesen gelesen, dass iwie erste der operator new aufgerufen wird und dann der konstruktor :Salso wird der Speicherplatz für eine objekt A gar nicht im Kontruktor alloziert sondern schoon vorher?
ich dachte immer man ruft den konstruktor auf, der alloziert den speicher, und macht noch n bischen was anderes und gibt dann ein Pointer auf das objekt zurück, aber jetzt verwirrt mich das mit operator new irgentwie :S, was macht der denn genau?
-
Wenn man davon ausgeht, dass der speicher garnicht vom konstruktor alloziert wird sondern schon vorher da war, währe es doch das neheliegenste, dass konstruktoren wie alle Memberfunktionen thiscall sind oder irre ich mich da?
-
Gustav Gans schrieb:
danke erstmal für diese informationen,
habe jetzt aber gelesen gelesen, dass iwie erste der operator new aufgerufen wird und dann der konstruktor :Salso wird der Speicherplatz für eine objekt A gar nicht im Kontruktor alloziert sondern schoon vorher?
ich dachte immer man ruft den konstruktor auf, der alloziert den speicher, und macht noch n bischen was anderes und gibt dann ein Pointer auf das objekt zurück, aber jetzt verwirrt mich das mit operator new irgentwie :S, was macht der denn genau?
Nö. Da Objekte auch auf dem Stack liegen können und es in C++ gar nicht möglich ist zur Laufzeit dynamisch Stackspeicher zu allozieren, muss der Speicher natürlich schon da sein. Der CTor ist wie der DTor eine ganz normale Memberfunktion.
-
Sooo,..
da mich das mal auch interessiert:std def:
class test { private: int i; public: test(){ this->i=2; __debugbreak(); } ~test() { this->i=0;}; }; int _tmain(int argc, _TCHAR* argv[]) { test blub; return 0; }
daraus wird:
class test { private: int i; public: test(){ 00411450 push ebp 00411451 mov ebp,esp 00411453 sub esp,0CCh 00411459 push ebx 0041145A push esi 0041145B push edi 0041145C push ecx 0041145D lea edi,[ebp-0CCh] 00411463 mov ecx,33h 00411468 mov eax,0CCCCCCCCh 0041146D rep stos dword ptr es:[edi] 0041146F pop ecx 00411470 mov dword ptr [ebp-8],ecx this->i=2; 00411473 mov eax,dword ptr [this] 00411476 mov dword ptr [eax],2 __debugbreak(); 0041147C int 3 } 0041147D mov eax,dword ptr [this] 00411480 pop edi 00411481 pop esi 00411482 pop ebx 00411483 mov esp,ebp 00411485 pop ebp 00411486 ret ~test() { this->i=0;}; 004114A0 push ebp 004114A1 mov ebp,esp 004114A3 sub esp,0CCh 004114A9 push ebx 004114AA push esi 004114AB push edi 004114AC push ecx 004114AD lea edi,[ebp-0CCh] 004114B3 mov ecx,33h 004114B8 mov eax,0CCCCCCCCh 004114BD rep stos dword ptr es:[edi] 004114BF pop ecx 004114C0 mov dword ptr [ebp-8],ecx 004114C3 mov eax,dword ptr [this] 004114C6 mov dword ptr [eax],0 004114CC pop edi 004114CD pop esi 004114CE pop ebx 004114CF mov esp,ebp 004114D1 pop ebp 004114D2 ret int _tmain(int argc, _TCHAR* argv[]) { 004113B0 push ebp 004113B1 mov ebp,esp 004113B3 sub esp,0D8h 004113B9 push ebx 004113BA push esi 004113BB push edi 004113BC lea edi,[ebp-0D8h] 004113C2 mov ecx,36h 004113C7 mov eax,0CCCCCCCCh 004113CC rep stos dword ptr es:[edi] test blub; 004113CE lea ecx,[blub] 004113D1 call test::test (411154h) return 0; 004113D6 mov dword ptr [ebp-0D4h],0 004113E0 lea ecx,[blub] 004113E3 call test::~test (4110F0h) 004113E8 mov eax,dword ptr [ebp-0D4h] } 004113EE push edx 004113EF mov ecx,ebp 004113F1 push eax 004113F2 lea edx,[ (411414h)] 004113F8 call @ILT+135(@_RTC_CheckStackVars@8) (41108Ch) 004113FD pop eax 004113FE pop edx 004113FF pop edi 00411400 pop esi 00411401 pop ebx 00411402 add esp,0D8h 00411408 cmp ebp,esp 0041140A call @ILT+325(__RTC_CheckEsp) (41114Ah) 0041140F mov esp,ebp 00411411 pop ebp 00411412 ret
der this ptr wird dabei in ecx gespeichert,...
nun mit __cdecl:
class test { private: int i; public: __cdecl test(){ this->i=2; __debugbreak(); } ~test() { this->i=0;}; }; int _tmain(int argc, _TCHAR* argv[]) { test blub; return 0; }
daraus wird:
class test { private: int i; public: __cdecl test(){ 00411450 push ebp 00411451 mov ebp,esp 00411453 sub esp,0CCh 00411459 push ebx 0041145A push esi 0041145B push edi 0041145C push ecx 0041145D lea edi,[ebp-0CCh] 00411463 mov ecx,33h 00411468 mov eax,0CCCCCCCCh 0041146D rep stos dword ptr es:[edi] 0041146F pop ecx 00411470 mov dword ptr [ebp-8],ecx this->i=2; 00411473 mov eax,dword ptr [this] 00411476 mov dword ptr [eax],2 __debugbreak(); 0041147C int 3 } 0041147D mov eax,dword ptr [this] 00411480 pop edi 00411481 pop esi 00411482 pop ebx 00411483 mov esp,ebp 00411485 pop ebp 00411486 ret ~test() { this->i=0;}; 004114A0 push ebp 004114A1 mov ebp,esp 004114A3 sub esp,0CCh 004114A9 push ebx 004114AA push esi 004114AB push edi 004114AC push ecx 004114AD lea edi,[ebp-0CCh] 004114B3 mov ecx,33h 004114B8 mov eax,0CCCCCCCCh 004114BD rep stos dword ptr es:[edi] 004114BF pop ecx 004114C0 mov dword ptr [ebp-8],ecx 004114C3 mov eax,dword ptr [this] 004114C6 mov dword ptr [eax],0 004114CC pop edi 004114CD pop esi 004114CE pop ebx 004114CF mov esp,ebp 004114D1 pop ebp 004114D2 ret int _tmain(int argc, _TCHAR* argv[]) { 004113B0 push ebp 004113B1 mov ebp,esp 004113B3 sub esp,0D8h 004113B9 push ebx 004113BA push esi 004113BB push edi 004113BC lea edi,[ebp-0D8h] 004113C2 mov ecx,36h 004113C7 mov eax,0CCCCCCCCh 004113CC rep stos dword ptr es:[edi] test blub; 004113CE lea ecx,[blub] 004113D1 call test::test (411154h) return 0; 004113D6 mov dword ptr [ebp-0D4h],0 004113E0 lea ecx,[blub] 004113E3 call test::~test (4110F0h) 004113E8 mov eax,dword ptr [ebp-0D4h] } 004113EE push edx 004113EF mov ecx,ebp 004113F1 push eax 004113F2 lea edx,[ (411414h)] 004113F8 call @ILT+135(@_RTC_CheckStackVars@8) (41108Ch) 004113FD pop eax 004113FE pop edx 004113FF pop edi 00411400 pop esi 00411401 pop ebx 00411402 add esp,0D8h 00411408 cmp ebp,esp 0041140A call @ILT+325(__RTC_CheckEsp) (41114Ah) 0041140F mov esp,ebp 00411411 pop ebp 00411412 ret
nun mit __thiscall:
class test { private: int i; public: __thiscall test(){ this->i=2; __debugbreak(); } ~test() { this->i=0;}; }; int _tmain(int argc, _TCHAR* argv[]) { test blub; return 0; }
class test { private: int i; public: __thiscall test(){ 00411450 push ebp 00411451 mov ebp,esp 00411453 sub esp,0CCh 00411459 push ebx 0041145A push esi 0041145B push edi 0041145C push ecx 0041145D lea edi,[ebp-0CCh] 00411463 mov ecx,33h 00411468 mov eax,0CCCCCCCCh 0041146D rep stos dword ptr es:[edi] 0041146F pop ecx 00411470 mov dword ptr [ebp-8],ecx this->i=2; 00411473 mov eax,dword ptr [this] 00411476 mov dword ptr [eax],2 __debugbreak(); 0041147C int 3 } 0041147D mov eax,dword ptr [this] 00411480 pop edi 00411481 pop esi 00411482 pop ebx 00411483 mov esp,ebp 00411485 pop ebp 00411486 ret ~test() { this->i=0;}; 004114A0 push ebp 004114A1 mov ebp,esp 004114A3 sub esp,0CCh 004114A9 push ebx 004114AA push esi 004114AB push edi 004114AC push ecx 004114AD lea edi,[ebp-0CCh] 004114B3 mov ecx,33h 004114B8 mov eax,0CCCCCCCCh 004114BD rep stos dword ptr es:[edi] 004114BF pop ecx 004114C0 mov dword ptr [ebp-8],ecx 004114C3 mov eax,dword ptr [this] 004114C6 mov dword ptr [eax],0 004114CC pop edi 004114CD pop esi 004114CE pop ebx 004114CF mov esp,ebp 004114D1 pop ebp 004114D2 ret int _tmain(int argc, _TCHAR* argv[]) { 004113B0 push ebp 004113B1 mov ebp,esp 004113B3 sub esp,0D8h 004113B9 push ebx 004113BA push esi 004113BB push edi 004113BC lea edi,[ebp-0D8h] 004113C2 mov ecx,36h 004113C7 mov eax,0CCCCCCCCh 004113CC rep stos dword ptr es:[edi] test blub; 004113CE lea ecx,[blub] 004113D1 call test::test (411154h) return 0; 004113D6 mov dword ptr [ebp-0D4h],0 004113E0 lea ecx,[blub] 004113E3 call test::~test (4110F0h) 004113E8 mov eax,dword ptr [ebp-0D4h] } 004113EE push edx 004113EF mov ecx,ebp 004113F1 push eax 004113F2 lea edx,[ (411414h)] 004113F8 call @ILT+135(@_RTC_CheckStackVars@8) (41108Ch) 004113FD pop eax 004113FE pop edx 004113FF pop edi 00411400 pop esi 00411401 pop ebx 00411402 add esp,0D8h 00411408 cmp ebp,esp 0041140A call @ILT+325(__RTC_CheckEsp) (41114Ah) 0041140F mov esp,ebp 00411411 pop ebp 00411412 ret
soooo,.. wer findet den fehler
-
soo und nochmal die stack order angucke:
test blub(15,16); 004113CE push 10h 004113D0 push 0Fh 004113D2 lea ecx,[blub] 004113D5 call test::test (4111D6h)
und der ctor
test(int a, int b){ 00411450 push ebp 00411451 mov ebp,esp 00411453 sub esp,0CCh 00411459 push ebx 0041145A push esi 0041145B push edi 0041145C push ecx 0041145D lea edi,[ebp-0CCh] 00411463 mov ecx,33h 00411468 mov eax,0CCCCCCCCh 0041146D rep stos dword ptr es:[edi] 0041146F pop ecx 00411470 mov dword ptr [ebp-8],ecx this->i=a; 00411473 mov eax,dword ptr [this] 00411476 mov ecx,dword ptr [a] 00411479 mov dword ptr [eax],ecx __debugbreak(); 0041147B int 3 } 0041147C mov eax,dword ptr [this] 0041147F pop edi 00411480 pop esi 00411481 pop ebx 00411482 mov esp,ebp 00411484 pop ebp 00411485 ret 8
mit __cdecl
test blub(15,16); 004113CE push 10h 004113D0 push 0Fh 004113D2 lea ecx,[blub] 004113D5 call test::test (4111D6h)
der ctor
__cdecl test(int a, int b){ 00411450 push ebp 00411451 mov ebp,esp 00411453 sub esp,0CCh 00411459 push ebx 0041145A push esi 0041145B push edi 0041145C push ecx 0041145D lea edi,[ebp-0CCh] 00411463 mov ecx,33h 00411468 mov eax,0CCCCCCCCh 0041146D rep stos dword ptr es:[edi] 0041146F pop ecx 00411470 mov dword ptr [ebp-8],ecx this->i=a; 00411473 mov eax,dword ptr [this] 00411476 mov ecx,dword ptr [a] 00411479 mov dword ptr [eax],ecx __debugbreak(); 0041147B int 3 } 0041147C mov eax,dword ptr [this] 0041147F pop edi 00411480 pop esi 00411481 pop ebx 00411482 mov esp,ebp 00411484 pop ebp 00411485 ret 8
jetzt nochmal mit __thiscall
test blub(15,16); 004113CE push 10h 004113D0 push 0Fh 004113D2 lea ecx,[blub] 004113D5 call test::test (4111D6h)
__thiscall test(int a, int b){ 00411450 push ebp 00411451 mov ebp,esp 00411453 sub esp,0CCh 00411459 push ebx 0041145A push esi 0041145B push edi 0041145C push ecx 0041145D lea edi,[ebp-0CCh] 00411463 mov ecx,33h 00411468 mov eax,0CCCCCCCCh 0041146D rep stos dword ptr es:[edi] 0041146F pop ecx 00411470 mov dword ptr [ebp-8],ecx this->i=a; 00411473 mov eax,dword ptr [this] 00411476 mov ecx,dword ptr [a] 00411479 mov dword ptr [eax],ecx __debugbreak(); 0041147B int 3 } 0041147C mov eax,dword ptr [this] 0041147F pop edi 00411480 pop esi 00411481 pop ebx 00411482 mov esp,ebp 00411484 pop ebp 00411485 ret 8
obwohl der stack cleanup unterschiedlich sein soll, erkenne ich keinen,..
grüüße