Wie funktionieren Prozeduraufrufe in Assembler?

8

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.

    
int3 09.08.2009, 09:59
quelle

4 Antworten

12

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.

%Vor%

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%     
Nathan Fellman 09.08.2009, 10:33
quelle
2

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.

    
aib 09.08.2009 11:00
quelle
1
%Vor%

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.

    
Nick Dandoulakis 09.08.2009 10:17
quelle
-1

Ich glaube nicht, dass der Rückgabewert im Register AX

gespeichert ist     
A.Rashad 09.08.2009 10:04
quelle

Tags und Links