[ASM] MSVC function Prolog / Epilog code

Hallo,

ich hab ein Problem. Ich versuch mir gerade an Hand meherer Tut`s & Co die Funktionweise des Stacks klar machen. Also dacht ich, ich schreib am besten ein billiges Programm was einfach blos aus einer main Funktion und einem Funktionsaufruf besteht und sonst nix macht - und dissamblier das...

Also ich benutze WindowsXP und mein Testcompiler ist der MSVC 6.0
das hier ist der "Testcode" ;-) ich hab die Anzahl der lokalen Variablen in einer Funktion / und die Übergabeparameter verändert und wollte sehen wie sich der Funktionsprolog ändert.

Gleich vorn weg - die parameter haben keinen Einflus auf den Prologcode.
Außerdem konnte ich auch kein Unterschied zwischen Releasemodus und Debugmodus finden

PS: Die Cpp datei ins MSVC ziehen und F10 drücken (für Debugmodus) - danach Alt + F8, dann seht ihr den Assemblercode.

Code:
int fu()
{
int aa= 55;  // im Moment 2 lokale Variablen also   sub esp, 48h
int ga= 55;

return 1;
}

int main()
{
   fu();
return 0; 
}

Ergebnis:

//5 lokale Var --> sub esp, 54h
//4 lokale Var --> sub esp, 50h
//3 lokale Var --> sub esp, 4Ch
//2 lokale Var --> sub esp, 48h
//1 lokale Var --> sub esp, 44h
//0 lokale Var --> sub esp, 44h


also es ist ja offensichtlich das es pro lokaler Variable mehr, den Stackframe um 4 vergrössert, das erklärt sich ja auch mit der Größe des Intergerdatentyps.

Aber was ich nicht verstehe ist die tatsache dass das Stackframe überhaupt so übertrieben rießig gebaut wird !? 44h sind 68d ...

Weiss jemand wieso das so ist, wie es ist ? ;)

so und jetzt hab ich mir gleich noch den Assemblercode der main Funktion angeschaut.

Code:
int main()
{
return 0;
}

Kann mir jemand erklären was der Compiler da, wieso macht ! Damit kann ich ganz und gar nix anfangen.

Code:
112:  int main()
113:  {
00401200 55                   push        ebp
00401201 8B EC                mov         ebp,esp
00401203 83 EC 40             sub         esp,40h
00401206 53                   push        ebx
00401207 56                   push        esi
00401208 57                   push        edi
00401209 8D 7D C0             lea         edi,[ebp-40h]
0040120C B9 10 00 00 00       mov         ecx,10h
00401211 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
00401216 F3 AB                rep stos    dword ptr [edi]
114:
115:  return 0;
00401218 33 C0                xor         eax,eax
116:  }


Ja das war`s ;-)
 
Code:
push        ebp			// funktionsepilog: basepointer sichern
mov         ebp,esp		// funktionsepilog: neuer bp = aktueller stackpointer
sub         esp,40h		// 64 bytes speicher auf dem stack allokieren
push        ebx			// register ebx sichern
push        esi			// register esi sichern
push        edi			// register edi sichern
lea         edi,[ebp-40h]	// adresse von ebp-40h nach edi
mov         ecx,10h		// 10h nach ecx, anzahl der dwords die mit rep stos in den speicher geschrieben werden
mov         eax,0CCCCCCCCh	// CCCCCCCCh nach eax
rep stos    dword ptr [edi]	// eax nach *edi, hier wird CCCCCCCCh in den vorher allokierten speicher geschrieben	
xor         eax,eax		// EAX = 0   (return 0)
dieser code ist für debug zwecke. wenn du deinen code im release modus kompilierst, bleibt nur noch "xor eax,eax" übrig.

das erklärt also deine frage warum oben dein stackframe so groß ist. in den ersten 40h sind halt debug informationen.
 
WoW ! (bin beeindruckt :-) )

gut das ich mal jmd mit elitärem Assemblerwissen gefunden hab... (*honig-ums-maul-schmier*)

zeit das aus zu nutzen !

Frage 1:

Code:
0040102A 89 65 E8             mov         dword ptr [ebp-18h],esp
0040102D FF 15 04 40 40 00    call        dword ptr ds:[404004h]

ok nehm wir diese 2 Zeilen. kannst du mir vielleicht erklären was diese dword ptr sein soll ?
 
das ist ein zeiger (dword = 4bytes, ptr = pointer = zeiger) und der wert in eckigen klammern ist die entsprechende adresse.
 
Zurück
Oben