C Calling Conventions und Parameterübergabe
-
Hab mal ne Frage zu dem "push dword ptr [edi]", wie ist das zu interpretieren? Wieso gerade das Register EDI? verweißt EDI auf locale Variablen? Bzw. macht man das nicht eigentlich immer mit dem EBP?
Gruß Tobi
-
Mit dem Befehl "lea" wird die Adresse der Variablen "f" in das Register "edi" explizit geladen und dient liedlich zur Verdeutlichung dass man bei groesseren Datentypen eher mit Referenzen/Pointer arbeiten wuerde. Das Register selbst ist hier vollkommen zufaellig gewaehlt. Aus historischen Gruenden bevorzugen viele esi/edi zur Adressierung.
Da "f" hier (absolut willkuerlich) eine lokale Variable (Stack-Frame) ist, wuerde sich deren Adresse auch relativ zu "ebp" ergeben (erledigt der Compiler selbst).
Man koennte genausogut schreiben:push dword ptr [f+4] push dword ptr [f]
-
hellihjb könntest du mir noch explizit schreiben wie das Poppen vom Stack nach dem Aufruf der Funktion mit der Convention __cdecl funktioniert. Also das Programm von oben noch mal nehmen? Ich hab es gestern geschafft, den Stack zu poppen und damit mein Programm-Thread unkillbar zu machen. Selbst der Taskmanager war nicht mehr in der Lage den Prozess zu killen. Vermutlich habe ich irgendwelche Rücksprungadresse vom Stack einfach mal weggepoppt. Wäre sehr nett.
-
Du pusht ja 5 Dwords auf den Stack (wobei der Stack-Pointer dekrementiert) und musst die hinterher wieder "runterpoppen" was effektiv nichts anderes ist als den Stack-Pointer wieder entsprechend zu erhoehen:
void __cdecl print_cdecl(char c, short s, int i, double f) { printf("%c, %d, %d, %f\n", c, s, i, f); } void asm_cdecl(void) { double f = 2.138; _asm { push dword ptr [f+4] push dword ptr [f] push 0x2000 // i = 2000h = 8192d push 0x0c // s = 0ch = 12d push 'x' // c = 'x' call print_cdecl // call print function add esp,4*5 } }
-
Ok, danke. Noch was. Auch wenn das jetzt ne doofe Frage ist. Warum ist 'x', 0x0c, 0x2000 ein dword? 'x' ist ein Byte lang, 0x0c ebenfalls. Und 0x2000 ist ein Word lang. Oder pusht er automatisch immer ein Dword auch wenn der Inhalt eigentlich kein Dword ist?
Edit: Und in der Definition ist c ja auch als Char deklariert also auch kein Dword!
-
Wie hier nachzulesen ist:
All arguments are widened to 32 bits when they are passed
-
Ah ok. Wenn ich das jetzt also richtig verstehe, dann passiert folgendes:
esp-offset stack printf -0 hier wollen wir wieder zurück --- -0 ... -4 dword ptr [f+4] castet das intern -4 ... -8 dword ptr [f] nach double -8 ... -12 0x2000 castet das intern nach int -12 ... -16 0x0c castet das intern nach short -16 ... -20 'x' castet das intern nach char
-
Es ist nicht notwendig zu casten.
Die Parameter stehen in gegebener Reihenfolge im Speicher.
Die Variablen und deren Groessen sind dem Compiler durch die Parameterliste bekannt und er liesst diese beim Zugriff einfach an der entsprechenden Speicherstelle aus.
-
Ich hab mal noch eine Frage und zwar zur __thiscall convention.
ECX bekommt die Referenz zum Klasseobject, und wie wird der rest also die Parameter mitgeteilt?typedef void (__thiscall *fpFunc)( int ); fpFunc fpfunc = (fpSetNewValue)(0x12345678); _asm mov ecx, dword ptr ds:[0x87654321] fpNew( 2 );
So gehts nicht. Aber wie dann?
Gruß Tobi
-
Hat sich erledigt.