Freigeben über


Parameterübergabe

Die ersten vier ganzzahligen Argumente werden in Registern übergeben. Ganzzahlige Werte werden (in Reihenfolge von links nach rechts) in RCX, RDX, R8 und R9 übergeben. Das vierte und alle weiteren Argumente werden an den Stapel übergeben. Alle Argumente sind in den Registern rechts ausgerichtet. Dies geschieht, damit der Aufgerufene die oberen Bits des Registers gegebenenfalls ignorieren und nur auf den erforderlichen Teil des Registers zugreifen kann.

Gleitkomma-Argumente und Argumente mit doppelter Genauigkeit werden in XMM0 bis XMM3 (bis 4) mit dem Ganzzahlslot (RCX, RDX, R8 und R9) übergeben, der normalerweise für den ignorierten Hauptslot verwendet würde (siehe Beispiel) und umgekehrt.

__m128-Typen, Arrays und Zeichenfolgen werden nie als unmittelbarer Wert übergeben, sondern es wird ein Zeiger an den vom Aufrufer belegten Speicher übergeben. Strukturen oder Unions mit 8, 16, 32 oder 64 Bits und __m64 werden wie ganze Zahlen derselben Größe übergeben. Strukturen oder Unions mit anderen als diesen Größen werden als Zeiger auf den vom Aufrufer belegten Arbeitsspeicher übergeben. Der vom Aufrufer belegte temporäre Speicher für diese als Zeiger übergebenen Aggregattypen (einschließlich __m128) ist auf 16 Byte ausgerichtet.

Systeminterne Funktionen, die keinen Stapelspeicher zuweisen und keine anderen Funktionen aufrufen, können andere flüchtige Register für die Übergabe zusätzlicher Registerargumente verwenden, da eine enge Bindung zwischen dem Compiler und der Implementierung der systeminternen Funktion besteht. Hier bietet sich eine weitere Gelegenheit zur Verbesserung der Leistung.

Der Aufgerufene hat die Aufgabe, die Registerparameter bei Bedarf in ihrem Shadow-Speicher zu sichern.

In der folgenden Tabelle ist zusammengefasst, wie Parameter übergeben werden:

Parametertyp

Übergabe

Gleitkomma

Erste 4 Parameter: XMM0 bis XMM3. Weitere Parameter werden an den Stapel übergeben.

Integer

Erste 4 Parameter: RCX, RDX, R8, R9. Weitere Parameter werden an den Stapel übergeben.

Aggregate (8, 16, 32 oder 64 Bits) und __m64

Erste 4 Parameter: RCX, RDX, R8, R9. Weitere Parameter werden an den Stapel übergeben.

Aggregate (sonstige)

Durch Zeiger. Die ersten 4 Parameter werden als Zeiger in RCX, RDX, R8 und R9 übergeben.

__m128

Durch Zeiger. Die ersten 4 Parameter werden als Zeiger in RCX, RDX, R8 und R9 übergeben.

Beispiel 1 für die Argumentübergabe: nur ganze Zahlen

func1(int a, int b, int c, int d, int e);  
// a in RCX, b in RDX, c in R8, d in R9, e pushed on stack

Beispiel 2 für die Argumentübergabe: nur Gleitkommazahlen

func2(float a, double b, float c, double d, float e);  
// a in XMM0, b in XMM1, c in XMM2, d in XMM3, e pushed on stack

Beispiel 3 für die Argumentübergabe: Gemischte Ganz- und Gleitkommazahlen

func3(int a, double b, int c, float d);  
// a in RCX, b in XMM1, c in R8, d in XMM3

Beispiel 4 für die Argumentübergabe: __m64, __m128 und Aggregate

func4(__m64 a, _m128 b, struct c, float d);
// a in RCX, ptr to b in RDX, ptr to c in R8, d in XMM3

Siehe auch

Referenz

Aufrufkonvention