Ich fing gerade an, an ASM zu basteln und bin mir nicht sicher, ob mein Verständnis von Prozeduraufrufen korrekt ist.
sagen an einem Punkt im Code gibt es einen Prozeduraufruf
%Vor%und die Prozedur besteht aus nur einem Befehl, ret:
%Vor%Was wäre der Effekt dieses Prozeduraufrufs und wo würde der Rückgabewert gespeichert? Ich habe irgendwo gelesen, dass ein Rückgabewert von 2 Bytes in AX gespeichert würde, aber wenn ich den Prozeduraufruf durch
ersetze %Vor%(zusammen mit den notwendigen NOPs) stürzt das Programm ab.
im x86-Assembler bedeutet der Parameter für den Befehl ret
:
RET immediate
Kehre zur aufrufenden Prozedur zurück und öffne sofortige Bytes vom Stapel.
(zitiert aus Intel® 64 und IA-32 Architectures Softwareentwicklerhandbüchern Band 2B )
Also wenn du tippst:
%Vor% Sie sagen der CPU, dass sie unmittelbar nach dem call
zum Befehl zurückkehren und 4 Bytes vom Stapel entfernen sollen. Das ist großartig, wenn Sie 4 Bytes vor dem Aufruf auf den Stack geschoben haben.
Beachten Sie, dass dies nichts mit dem Rückgabewert zu tun hat. Tatsächlich kann eine Prozedur in Assembly nicht angeben, dass ein Wert ein return -Wert ist. Dies geschieht alles durch Konvention. Die meisten Compiler, die mir bekannt sind, verwenden EAX
, um den Rückgabewert zu speichern, aber dies gilt nur, weil die aufrufende -Funktion das Ergebnis dort erwartet.
Ihr Aufrufcode wäre also:
%Vor%und Ihre Funktion, die den Wert 4 zurückgibt, wäre:
%Vor%Es kommt darauf an, dass die Aufrufkonvention verwendet wird. Ich werde den Wikipedia-Artikel hier nicht wiederholen, lesen Sie einfach die Definition.
In der C-Aufrufkonvention würde der Rückgabewert beispielsweise in EAX / AX / AL sein. Ihre Einzelinstruktion hat keine: Sie ist eine void-Funktion, die ungefähr 4 Bytes von Parametern (möglicherweise ein einzelnes int) benötigt, die nichts tun. Da es die Pflicht des Angerufenen ist, den Stapel in dieser Aufrufkonvention zu bereinigen, funktioniert das Ignorieren und das Ersetzen des Aufrufs durch eine "mov ax" nicht.
Ich vermute auch, dass Sie beim Lesen eines 16-Bit-Dokuments an der 32-Bit-Assembly herumgebastelt haben. Es ist kein großes Problem, aber Sie sollten sich der Unterschiede bewusst sein.
wir zusätzlich verringern den ESP, wenn wir vor dem Aufruf der Prozedur Argumente im Stapel übertragen hatten.
Wenn es Push-Argumente gibt, stürzt dein Programm ab, weil du sie nicht platzierst. Der Rückgabe-Offset für die aktuelle Prozedur ist falsch, da er einen Wert von einem der Push-Argumente als Offset erhält.
Tags und Links assembly x86 function-calls call