Frage

Ich habe gerade angefangen mit ASM bastelte und ich bin nicht sicher, ob mein Verständnis von Prozeduraufrufen korrekt ist.

sagen irgendwann im Code gibt es einen Prozeduraufruf

call dword ptr[123]

und das Verfahren besteht aus nur einem Befehl, ret:

ret 0004

Was würde die Wirkung dieser Prozeduraufruf sein, und wo wäre der Rückgabewert gespeichert? Ich habe irgendwo gelesen, dass ein Rückgabewert von 2 Bytes würde in AX gespeichert werden, aber wenn ich den Prozeduraufruf ersetzen, indem

mov AX, 0004

(zusammen mit den notwendigen NOPs) das Programm abstürzt.

War es hilfreich?

Lösung

in x86-Assembler der Parameter auf die ret Anweisung bedeutet:

RET immediate

  

Zurück zur Aufrufprozedur und Pop sofort Bytes vom Stapel.

(unter Angabe von Intel® 64 und IA-32 Architektur Software Developer Manuals Vol 2B )

Also, wenn Sie ein:

ret 0004

Sie sagen die CPU auf die Anweisung zurückzukehren unmittelbar nach dem call und 4 Bytes vom Stapel Pop. Das ist toll, wenn man gedrückt 4 Bytes auf den Stapel vor dem Aufruf.

push eax
call dword ptr[123]

Beachten Sie, dass dies nichts mit dem Rückgabewert zu tun hat. In der Tat hat ein Verfahren in Versammlung keine Möglichkeit, die Angabe, dass ein Wert ist ein zurück Wert. Dies alles wird durch Konvention getan. Die meisten Compiler, von denen ich weiß, wird EAX verwenden den Rückgabewert zu halten, aber das gilt nur, weil die Aufruf Funktion wird das Ergebnis erwarten es.

So Ihre Berufung Code wäre:

call dword ptr [123]
mov dword ptr [result], eax

und Ihre Funktion, die den Wert zurückgibt 4 wäre:

mov eax, 4
ret

Andere Tipps

Es hängt alles von der Aufrufkonvention verwendet wird. Ich werde den Wikipedia-Artikel hier nicht wiederholen, sondern nur die Definition lesen.

In der C-Aufrufkonvention zum Beispiel wäre der Rückgabewert in EAX / AX / AL. Ihre Single-Instruction haben nicht ein: Es ist eine Leere Funktion um 4 Byte Parameter unter (möglicherweise ein einzelnes int), die nichts tut. Da es die Angerufene Pflicht zu bereinigen, den Stapel in dieser Aufrufkonvention ist, ignoriert mit einem ‚mov ax‘ das und ersetzt den Anruf zu tun funktioniert nicht.

Auch vermute ich Sie mit 32-Bit-Baugruppe bastelt werden kann, während ein 16-Bit-Dokument zu lesen. Es ist kein großes Problem, aber Sie sollten die Unterschiede bewusst sein.

// possibly there are arguments pushed here
...
call dword ptr[123] // push next OP code offset in the stack and jump to procedure

// procedure
...
ret 0004 // pop offset, set EIP to that offset and decrease ESP by 4

wir zusätzlich das ESP ab, wenn wir Argumente in dem Stapel vor dem Aufruf der Prozedur geschoben hatte.


Wenn gedrückt Argumente sind, stürzt Ihr Programm, weil Sie sie nicht Pop. Der Rückversatz für den aktuellen Vorgang wird falsch sein, da sie einen Wert von einem der geschoben Argumente bekommen als Offset.

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top