Delphi-Quellcode:
procedure Prc(var a{[EAX]}: Cardinal);
procedure Swap1(var a{[EAX]},b{[EDX]}: Cardinal);
procedure Proc(a{AX}: Word);
procedure Proc(b{AX}: Word);
procedure Proc(a{EAX}, b{EDX}, c{ECX} : Integer);
function Proc(a{EAX}, b{EDX}, c{ECX} : Integer; d : Byte; var e : Byte; var f: Cardinal) : Word; {EAX}
// D,E,F liegen auf dem Stack
Im letzten Beispiel entsteht eine Mischübergabe, aus Register und Stack.
Die ersten 3 ordinalen Paramater werden in den Registern EAX,EDX,ECX übergeben. Die restlichen Paramter liegen auf dem Stack. Wobei var E,F Zeiger auf die Speicheradresse sind.
Delphi-Quellcode:
function Proc(a
{EAX}, b
{EDX}, c
{ECX} : Integer; d : Byte;
var e : Byte;
var f: Cardinal) : Word;
asm
// compiler erzeugt Stackframe autom.
// PUSH EBP
// MOV EBP,ESP
PUSH EBX
// EBX sichern
MOV EBX,[A]
// == MOV EBX,[EAX]
MOV EBX,[B]
// == MOV EBX,[EDX]
MOV EBX,[C]
// == MOV EBX,[ECX]
MOV BL,D
// == MOV BL,[EBP + ?]
MOV EBX,E
// == MOV EBX,[EBP + ?]
MOV BL,[EBX]
// BL := E
MOV EBX,F
MOV EBX,[EBX]
// EBX := F
MOV AX,BX
// Result := BX
MOV @Result,BX
// Result := BX
POP EBX
// Stackframe entfernen, autm. durch Compiler
// POP EBP
end;
Man sieht also das ein cleverer Delphi Programmier versucht seine Proceduren mit maximal 3 ordinalen Paramtern zu versehen. Bei Methoden mit 2 ordinalen Paramtern da in EAX = Self steht. Durch dieses Vorgehen kann der Optimierer innerhalb der Procedure den Stackframe wegoptimieren. Dies spart Stack + Zeit.
Sollte der Programmierer nicht ordinale Parameter benutzen wollen so wird er dann immer diesen Paramter in einen vergleichbaren ordinalen Typ konvertieren. Z.b. Zeiger auf Double, oder var Double;
Gruß Hagen