Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - function Rückgabewert (Assembler)


Steve_B - Do 02.09.04 18:38
Titel: function Rückgabewert (Assembler)
Hallo!

Kann eine Assembler-Funktion nur ein Byte / Char (al) oder ein Word (ax) zurückliefern oder geht das irgendwie auch mit größeren Zahlen >65536 (zwei Register = 32 Bit)?

Delphi-Quelltext
1:
2:
3:
4:
function MachWas: Word;
asm
  mov ax,0FFFFh
end;
(Gut, so ist die Funktion ziemlich sinnlos, es geht mir halt nur um den Rückgabewert...)

Thanks!


.Chef - Do 02.09.04 18:59


Delphi-Quelltext
1:
2:
3:
4:
5:
function MachWas : Integer;
asm
  mov eax,0FFFFFFFFh
  mov Result,eax
end;


Gruß,
Jörg


UC-Chewie - Do 02.09.04 19:36

Das zweite mov ist unnötig, da bei der Aufrufkonvention register (die verwendet wird, wenn nix dabei steht) der Rückgabebwert per Definition in EAX liegt.


Anonymous - Fr 03.09.04 18:35

Nicht ganz. Result wird auf dem Stack abgelegt und erst am Ende der Fkt nach EAX geschrieben.
(Natürlich nur wenn es auch benutzt wird, ansonsten kann man getrost EAX benutzen)


AndyB - Fr 03.09.04 21:28

obbschtkuche hat folgendes geschrieben:
Nicht ganz. Result wird auf dem Stack abgelegt und erst am Ende der Fkt nach EAX geschrieben.
(Natürlich nur wenn es auch benutzt wird, ansonsten kann man getrost EAX benutzen)

So, so.
Hast du dir den Code von oben mal im Debugger angeschaut?
Da steht doch glatt:

Delphi-Quelltext
1:
2:
MachWas:  mov eax,0FFFFFFFFh
          mov eax,eax

Na sowas. Hat "mov eax, eax" etwa etwas mit dem Stack zu tun?

Der Compiler lagert Result schon auch auf dem Stack aus, nur eben nicht immer und vor allem nicht in reinen Assembler-Funktionen. Da entspricht Result in 98% aller Fälle EAX. Bei Fließkommazahlen ist das anders und bei Int64 wird noch EDX misbraucht.


UC-Chewie - Sa 04.09.04 10:31

Zu diesem Thema auch interessant:
Online-Hilfe -> ObjectPascal-Referenz -> Ablaufsteuerung -> Parameter und Funktionsergebnisse -> Funktionsergebnisse

(zumindest heißts so bei Delphi5).


Anonymous - Sa 04.09.04 10:56

pfffff.

AndyB hat folgendes geschrieben:

So, so.
Hast du dir den Code von oben mal im Debugger angeschaut?


Natürlich.

AndyB hat folgendes geschrieben:

Da steht doch glatt:

Delphi-Quelltext
1:
2:
MachWas:  mov eax,0FFFFFFFFh
          mov eax,eax

Na sowas. Hat "mov eax, eax" etwa etwas mit dem Stack zu tun?


Na sowas. Hat das etwa wirklich was mit dem Delphi-Debugger zu tun?


Delphi-Quelltext
1:
2:
3:
4:
5:
function MachWas : Integer;
asm
  mov eax,0FFFFFFFFh
  mov Result,eax
end;



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
push ebp
mov  ebp, esp
push ecx
mov  eax, $ffffffff
mov  [ebp-$04], eax
mov  eax, [ebp-$04]
pop  ecx
pop  ebp
ret


Und jetzt behaupte bloß nicht Result wäre da nicht als lokale Variable im Stack. Hast du vielleicht in den Einstellungen irgendwas geändert dass solche unnützen Sachen rausoptimiert sind?


UC-Chewie - Sa 04.09.04 12:17

Ich schätz mal, ihr redet da über andere Funktionen. Bei der Funktion:

Delphi-Quelltext
1:
2:
3:
4:
5:
function MachWas : Integer;  
asm  
  mov eax,0FFFFFFFFh  
  mov Result,eax  
end;

Hier wird Result als lokale Variable auf dem Stack angelegt. Und wie man im erzeugten Code sehen kann, wird der Wert von Result danach wieder in EAX kopiert. Die Zuweisung an Result ist hier also unnötig und führt zu identischem Laufzeitverhalten, nur einigen Anweisungen mehr.


AndyB - Sa 04.09.04 17:25

UC-Chewie hat folgendes geschrieben:
Ich schätz mal, ihr redet da über andere Funktionen.

Eigentlich nicht. Aber höchstwahrscheinlich von anderen Delphi Versionen. Ich habe obiges nicht nachgeprüft, da ich das "mov eax,eax" schon mal in einem meiner Programme gefunden habe. Der i386 kann damit anscheinend nichts anfangen und zerstört dabei das eax Register. Deswegen wird Borland das wahrscheinlich ausgebessert haben. Es war igrendwo zwischen Delphi 6 und Delphi 6 Update 2. Damit entschuldige ich mich in aller Förmlichkeit bei obbschtkuche. :oops: