Assembler-Prozeduren und -Funktionen

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Verwendung des integrierten Assemblers - Index

Mit dem Inline-Assembly-Sprachcode können Sie komplette Prozeduren und Funktionen schreiben, für die keine begin...end-Anweisung erforderlich ist.

Compiler-Optimierungen

Der folgende Code ist ein Beispiel für eine gültige Funktion:

function LongMul(X, Y: Integer): Longint;
asm
  MOV  EAX,X
  IMUL    Y
end;

Der Compiler führt für diese Routinen verschiedene Optimierungen durch:

  • Der Compiler erstellt keinen Code zum Kopieren von Wert-Parametern in lokale Variablen. Dies betrifft alle Wert-Parameter vom Typ String und alle anderen Wert-Parameter, deren Größe nicht ein, zwei oder vier Byte beträgt. Innerhalb der Routine müssen derartige Parameter als var-Parameter behandelt werden.
  • Der Compiler weist keine Funktionsergebnis-Variable zu, und eine Referenz auf das Symbol @Result ist ein Fehler. Eine Ausnahme bilden Funktionen, die eine Referenz auf einen String, eine Variante oder ein Interface zurückliefern. Die aufrufende Routine weist diesen Typen immer einen @Result-Zeiger zu.
  • Der Compiler generiert nur Stack-Frames für verschachtelte Routinen, für Routinen mit lokalen Parametern oder für Routinen, die über Parameter im Stack verfügen.
  • Locals ist die Größe der lokalen Variablen, Params die Größe der Parameter. Wenn sowohl Locals als auch Params null ist, existiert kein Eintrittscode, und der Austrittscode besteht nur aus einer RET-Anweisung.

Der automatisch erzeugte Eintritts- und Austrittscode für Routinen sieht folgendermaßen aus:

PUSH   EBP         ;Present if Locals <> 0 or Params <> 0
MOV    EBP,ESP         ;Present if Locals <> 0 or Params <> 0
SUB    ESP,Locals      ;Present if Locals <> 0
; …
MOV    ESP,EBP         ;Present if Locals <> 0
POP    EBP         ;Present if Locals <> 0 or Params <> 0
RET    Params          ;Always present

Wenn lokale Variablen Varianten, lange Strings oder Interfaces enthalten, werden sie mit null initialisiert, aber nach der Verarbeitung nicht finalisiert.

Funktionsergebnisse

Assembly-Funktionen liefern ihre Ergebnisse folgendermaßen zurück.

32 Bit

  • Ordinale Werte werden in AL (8-Bit-Werte), AX (16-Bit-Werte) oder EAX (32-Bit-Werte) zurückgegeben.
  • Reelle Werte werden in ST(0) über den Register-Stack des Coprozessors zurückgegeben. (Currency-Werte werden mit dem Faktor 10000 skaliert.)
  • Zeiger einschließlich langer Strings werden in EAX zurückgeliefert.
  • Kurze Strings und Varianten werden an die temporären Adresse zurückgegeben, auf die @Result zeigt.


64 Bit

  • Werte, die 8 Byte oder kleiner sind, werden im Register RAX zurückgegeben.
  • Reelle Werte werden im Register XMM0 zurückgegeben.
  • Andere Typen werden per Referenz zurückgegeben. Der Zeigerwert der Referenz befindet sich im RAX, dessen Speicher durch die aufrufende Routine zugewiesen wird.

Intel 64-Spezifikationen

x64-Funktionen müssen vollständig in Assembly oder Pascal geschrieben werden, d.h. Assembler-Anweisungen werden nicht unterstützt, nur Inline-Assembly-Funktionen.

Pseudo-Ops wurden zur Unterstützung der Verwaltung der Stack-Verwendung in x64 hinzugefügt: .PARAMS, .PUSHNV, .SAVENV und .NOFRAME.

Pseudo-Op

Beschreibung

.PARAMS <Zahl>

Wird beim Aufruf von externen Funktionen zum Einrichten des Ergänzungsspeichers für Registerparameter gemäß der x64-Aufrufkonvention verwendet, da dies normalerweise nicht standardmäßig erfolgt. Damit steht eine Pseudovariable, @params, für die Übergabe von Stack-Parametern an aufgerufene Funktionen zur Verfügung. Verwenden Sie @params als ein Byte-Array, wobei der erste Stack-Parameter @params[32] ist. Die Speicherorte 0-31 repräsentieren die 4 Registerparameter.

.PUSHNV <Register>

Erzeugt Code zum Speichern und Wiederherstellen des allgemeinen, nichtflüchtigen Registers im Prolog und Epilog.

.SAVENV <XMM-Register>

Hat dieselbe Funktionalität wie .PUSHNV für nicht-flüchtige XMM-Register.

.NOFRAME

Erzwingt die Deaktivierung der Erzeugung eines Stack-Frame, solange keine lokalen Variablen deklariert sind und die Parameteranzahl < 4 ist. Verwenden Sie dieses Pseudo-Op nur für "Leaf"-Funktionen.

Stack-Abwicklung für PC-zugeordnete Erweiterungen

Siehe PC-zugeordnete Erweiterungen#Abwickeln von Assembly-Routinen.

Siehe auch