Dazu noch folgende Fragen:
- ENTER / LEAVE vorteilhaft gegenueber mov .../pop ...? (unterschiedliche Handhabung in den Compilern? Mein DJGPP verwendet letzteres)
Hat für C-Compiler keine Vorteile außer der Kürze. Auf alten CPUs unterscheiden sich die Instruktionen in der Ausführungsgeschwindigkeit.
- Warum speichert caller - falls notwendig - EAX, ECX, EDX?
- Warum speichert callee - falls notwendig - EBX, ESI, EDI?
Konvention. Die aufgerufene Funktion darf EAX, ECX, und EDX verändern, aber EBX, ESI, und EDI nicht. Wenn der Aufrufer EAX, ECX, oder EDX braucht, muss er sie deswegen selbst sichern und nach dem Aufruf wiederherstellen. Wenn der Aufgerufene EBX, ESI, oder EDI braucht, muss er sie selbst sichern und später wiederherstellen.
Die Einteilung in diese zwei Klassen hat vermutlich den Grund, dass die einen eher für Speicherzugriffe sind, die anderen für arithmetische Operationen. Aber bereits seit dem 386er ist diese Trennung obsolet.
- Wozu verwendet der callee den Bereich "temporary storage" (neben local variables)? Konkretes Beispiel?
Wenn dem Compiler bei aufwändigen Rechnungen die Register für Zwischenergebnisse ausgehen, speichert er die da.
- Ist "pop eip" gleich "ret"?
- Ist "push eip" plus "jmp foo" gleich "call foo"?
Wenn es das gäbe, dann ja.