Freigeben über


struct UNWIND_CODE

Aktualisiert: November 2007

Das Entladecode-Array wird zum Aufzeichnen der Folge von Vorgängen im Prolog verwendet, die sich auf nicht veränderliche Register und RSP auswirken. Jedes Codeelement hat das folgende Format:

UBYTE

Offset im Prolog

UBYTE: 4

Entladeoperationscode

UBYTE: 4

Operationsinfo

Das Array wird in absteigender Reihenfolge des Offsets im Prolog sortiert.

  • Offset im Prolog
    Offset vom Anfang des Prologs vom Ende der Anweisung, die diese Operation ausführt, plus 1 (d. h. der Offset des Starts der nächsten Anweisung).

  • Entladeoperationscode
    Hinweis: Bestimmte Operationscodes erfordern einen Offset ohne Vorzeichen für einen Wert im lokalen Stapelrahmen. Dies ist ein Offset vom Anfang (der niedrigsten Adresse) der festen Stapelzuweisung. Wenn das Frameregisterfeld in UNWIND_INFO 0 (null) ist, ist dies ein Offset von RSP. Wenn das Frameregisterfeld einen Wert ungleich 0 (null) hat, ist dies der Offset vom Speicherort von RSP zum Zeitpunkt der Einrichtung von FP reg. Dies entspricht FP reg minus dem FP reg-Offset (16 * der skalierte Frameregisteroffset in UNWIND_INFO). Wenn ein FP reg verwendet wird, kann ein Entladecode mit einem Offset erst verwendet werden, nachdem im Prolog FP reg eingerichtet wurde.

    Bei allen Opcodes mit Ausnahme von UWOP_SAVE_XMM128 und UWOP_SAVE_XMM128_FAR ist der Offset immer ein Vielfaches von 8, da alle relevanten Stapelwerte auf 8-Byte-Grenzen gespeichert sind (der Stapel selbst ist stets in 16 Byte ausgerichtet). Bei Operationscodes mit kurzem Offset (weniger als 512 K) enthält der letzte USHORT in den Knoten für diesen Code den Offset geteilt durch 8. Bei Operationscodes mit langem Offset (512 K <= Offset < 4 GB) enthalten die letzten beiden USHORT-Knoten für diesen Code den Offset (im Little-Endian-Format).

    Bei den Opcodes UWOP_SAVE_XMM128 und UWOP_SAVE_XMM128_FAR ist der Offset immer ein Vielfaches von 16, da alle 128-Bit-XMM-Operationen in einem in 16 Byte ausgerichteten Speicher erfolgen müssen. Deshalb wird ein Skalierungsfaktor von 16 für UWOP_SAVE_XMM128 verwendet, der Offsets von weniger als 1 M erlaubt.

    Für den Entladeoperationscode gibt es folgende Möglichkeiten:

    UWOP_PUSH_NONVOL (0)1 Knoten

    Ein nicht veränderliches Ganzzahlregister wird verschoben und RSP um 8 dekrementiert. Operationsinfo ist die Anzahl der Register. Beachten Sie, dass aufgrund der Beschränkungen für Epiloge UWOP_PUSH_NONVOL-Entladecodes zuerst im Prolog und dementsprechend zuletzt im Entladecode-Array auftreten müssen. Diese relative Anordnung gilt mit Ausnahme von UWOP_PUSH_MACHFRAME für alle anderen Entladecodes.

    UWOP_ALLOC_LARGE (1)2 oder 3 Knoten

    Zuweisen eines großen Bereichs auf dem Stapel. Dies kann in zwei Formen erfolgen. Wenn die Operationsinfo gleich 0 (null) ist, wird die Größe der Zuweisung geteilt durch 8 im nächsten Slot aufgezeichnet, sodass eine Zuweisung bis zu 512 K – 8 möglich ist. Wenn die Operationsinfo 1 ist, wird die unskalierte Größe der Zuweisung im Little-Endian-Format in den nächsten beiden Slots aufgezeichnet, sodass Zuweisungen bis zu 4 GB – 8 möglich sind.

    UWOP_ALLOC_SMALL (2)1 Knoten

    Zuweisen eines kleinen Bereichs auf dem Stapel. Die Größe der Zuweisung ist das Operationsinfofeld * 8 + 8, sodass Zuweisungen von 8 bis 128 Byte möglich sind.

    Für den Entladecode für eine Stapelreservierung sollte immer eine so kurze Codierung wie möglich verwendet werden:

    Zuweisungsgröße

    Entladecode

    8 bis 128 Byte

    UWOP_ALLOC_SMALL

    136 bis 512 K - 8-Byte

    UWOP_ALLOC_LARGE, Operationsinfo = 0

    512 K bis 4 G - 8 Byte

    UWOP_ALLOC_LARGE, Operationsinfo = 1

    UWOP_SET_FPREG (3)1 Knoten

    Erstellen Sie das Framezeigerregister, indem Sie für das Register einen Offset vom aktuellen RSP angeben. Der Offset entspricht dem Frameregisteroffset-Feld (skaliert) in UNWIND_INFO * 16 mit möglichen Offsets von 0 bis 240. Die Verwendung eines Offsets erlaubt die Erstellung eines Framezeigers, der auf die Mitte der festen Stapelzuweisung verweist. Dies unterstützt eine höhere Codedichte, da mehr Zugriffe für die Verwendung kurzer Anweisungsformen möglich sind. Beachten Sie, dass das Operationsinfofeld reserviert ist und nicht verwendet werden sollte.

    UWOP_SAVE_NONVOL (4)2 Knoten

    Ein nicht veränderliches Ganzzahlregister wird auf dem Stapel mit einem MOV anstelle eines PUSH gespeichert. Dies wird hauptsächlich zum platzsparenden Verpacken verwendet, bei dem ein nicht veränderliches Register auf dem Stapel in einer zuvor zugewiesenen Position gespeichert wird. Die Operationsinfo ist die Anzahl der Register. Der um 8 skalierte Stapeloffset wird im nächsten Entladeoperationscode-Slot aufgezeichnet, wie im Hinweis oben beschrieben.

    UWOP_SAVE_NONVOL_FAR (5)3 Knoten

    Ein nicht veränderliches Ganzzahlregister wird auf dem Stapel mit langem Offset gespeichert, wobei ein MOV anstelle eines PUSH verwendet wird. Dies wird hauptsächlich zum platzsparenden Verpacken verwendet, bei dem ein nicht veränderliches Register auf dem Stapel in einer zuvor zugewiesenen Position gespeichert wird. Die Operationsinfo ist die Anzahl der Register. Der unskalierte Stapeloffset wird in den nächsten beiden Entladeoperationscode-Slots aufgezeichnet, wie im Hinweis oben beschrieben.

    UWOP_SAVE_XMM128 (8)2 Knoten

    Die gesamten 128 Bits eines nicht veränderlichen XMM-Registers werden auf dem Stapel gespeichert. Die Operationsinfo ist die Anzahl der Register. Der um 16 skalierte Stapeloffset wird im nächsten Slot aufgezeichnet.

    UWOP_SAVE_XMM128_FAR (9)3 Knoten

    Die gesamten 128 Bits eines nicht veränderlichen XMM-Registers werden auf dem Stapel mit einem langen Offset gespeichert. Die Operationsinfo ist die Anzahl der Register. Der unskalierte Stapeloffset wird in den nächsten beiden Slots aufgezeichnet.

    UWOP_PUSH_MACHFRAME (10)1 Knoten

    Verschieben eines Computerframes. Dies wird verwendet, um die Auswirkungen eines Hardware-Interrupts oder einer Ausnahme aufzuzeichnen. Dies kann in zwei Formen erfolgen. Wenn die Operationsinfo 0 (null) ist, wurde Folgendes auf dem Stapel abgelegt:

    RSP+32

    SS

    RSP+24

    Alter RSP

    RSP+16

    EFLAGS

    RSP+8

    CS

    RSP

    RIP

    Ist die Operationsinfo 1, wurde stattdessen Folgendes abgelegt:

    RSP+40

    SS

    RSP+32

    Alter RSP

    RSP+24

    EFLAGS

    RSP+16

    CS

    RSP+8

    RIP

    RSP

    Fehlercode

    Dieser Entladecode tritt stets in einem Platzhalter-Prolog auf, der nie tatsächlich ausgeführt wird, sondern vor dem wirklichen Einstiegspunkt einer Interruptroutine als Platzhalter für die Simulation der Verschiebung eines Computerframes dient. UWOP_PUSH_MACHFRAME zeichnet diese Simulation auf, die angibt, dass der Computer konzeptuell wie folgt vorgegangen ist:

    Auslesen der RIP-Rückgabeadresse oben im Stapel in Temp

    Ablegen von SS

    Ablegen des alten RSP

    Ablegen der EFLAGS

    Ablegen von CS

    Ablegen von Temp

    Ablegen des Fehlercodes (wenn op info 1 ist)

    Die simulierte UWOP_PUSH_MACHFRAME-Operation dekrementiert RSP um 40 (op info ist 0) oder um 48 (op info ist 1).

  • Operationsinfo
    Die Bedeutung dieser 4 Bits ist abhängig vom Operationscode. Für die Codierung eines Allzweckregisters (ganzzahlig) wird folgende Zuordnung verwendet:

    0

    RAX

    1

    RCX

    2

    RDX

    3

    RBX

    4

    RSP

    5

    RBP

    6

    RSI

    7

    RDI

    8 bis 15

    R8 bis R15

Siehe auch

Referenz

Entladedaten für die Ausnahmebehandlung, Debuggerunterstützung