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 :S

    also 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 :S

    also 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


Log in to reply