Deskriptor (Prozessor)
Als Deskriptor bezeichnet man in Intel-x86-Prozessoren ab 80286 (eingeführt 1982) eine Struktur, welche ein Segment oder eine Funktion im Hauptspeicher beschreibt.
Ein Deskriptor hat eine Größe von 8 Byte und beinhaltet die Größe, die Position, die Zugriffsberechtigungen und Verwendung eines Segmentes. Neben den eben beschriebenen Speichersegmenten gibt es auch Systemsegmente, die zum Beispiel eine Betriebssystemfunktion markieren.
Deskriptoren kommen ausschließlich im Protected Mode vor und dienen beim 80286 Prozessor dazu, trotz der Registerbreite von 16 Bit, Protected Mode fähiger Software einen Adressraum von 24 Bit und somit bis zu 16 MiB Speicherplatz zur Verfügung zu stellen. Im Real Mode werden Deskriptoren nicht verwenden. Dort haben die Segmente eine konstante Größe von 64 KiB und der maximale Adressbereich ist auf 16 Bit begrenzt, womit ein maximaler Speicher von nur 1 MiB Größe adressiert werden kann.
Alle Deskriptoren werden in drei Tabellen eingeteilt.
- Die GDT (Global Descriptor Table) kann maximal 8192 Deskriptoren aufnehmen und ist für alle Prozesse verfügbar.
- Die LDT (Local Descriptor Table) ist eine Tabelle, die es mehrfach für einen Prozess geben kann und bei denen jeder Prozess seine eigenen LDTs hat. Aber es ist immer nur eine einzige LDT zur gleichen Zeit verfügbar. Bei einem Taskwechsel auf einen anderen Prozess wird auf eine LDT des anderen Prozesses umgeschaltet. Die LDT enthält Speichersegmente die als privat markiert sind und somit ausschließlich nur einem Prozess zur Verfügung stehen.
- Die dritte Tabelle ist die IDT (Interrupt Descriptor Table). Sie umfasst 256 Deskriptoren, wofür jeder Deskriptor die Startadresse des jeweiligen Interrupts markiert.
Segmentdeskriptoren im 16-/32-Bit Protected Mode
Abkürzung | Bezeichnung | Bedeutung |
---|---|---|
Base address | Basisadresse des Segments. Das Feld ist aus historischen Gründen in drei Bereiche aufgeteilt und insgesamt 32 Bit breit. Der 1. Teil besteht aus dem unteren Feld aus Bit 16 bis 31, der 2. Teil aus dem oberen Feld aus Bit 0 bis 7 und der 3. Teil aus Bit 24 bis 31. | |
G | Granularität | Wenn das Bit nicht gesetzt ist, dann kann die Segmentgröße in 1 Byte Schritten von 1 Byte bis 1 MiB gehen. Wenn das Bit gesetzt ist, dann kann die Segmentgröße in 4 Byte Schritten von 4 Kbyte bis 4 GByte gehen. |
D/B | Default Operand Size | Für Codesegmente: D=1: Operanden haben per Default 32 Bit; D=0: Operanden haben per Default 16 Bit. (Die Defaultwerte können durch ein "Operand Size Prefix" für den nachfolgenden Maschinenbefehl auf den jeweils anderen Wert geändert werden) |
L | Long | 64-bit code segment (Nur IA-32e Modus). In der Grafik Bit 21. |
AVL | available | steht dem Betriebssystem zur freien Verfügung. In der Grafik Bit 20 mit Bezeichner A. |
Segment Limit | Segmentgröße in Bytes oder in 4-KiB-Seiten. Der Modus wird durch das Granularität Bit 23 definiert. Dieses Feld ist zweigeteilt. Es wird aus dem unteren Feld, welches den 1. Teil darstellt, von Bit 0 bis Bit 15 und aus dem oberen Feld aus Bit 16 bis 19 gebildet, dieses bildet den zweiten Teil. Das Segment Limit ist insgesamt 20 Bit breit. | |
P | Präsent | P=1: Segment ist im Speicher vorhanden; P=0: Segment ist zurzeit nicht vorhanden (z. B. zurzeit ausgelagert). Zugriffe auf nicht präsente Segmente lösen eine Ausnahme aus (die vom Betriebssystem abgefangen und dazu genutzt werden kann, das fehlende Segment wieder einzuladen) |
DPL | Descriptor Privilige Level | Spezifiziert das Privileg Level des Segments. Der Wert kann den Wert 0 bis 3 annehmen. 0 steht für die privilegierteste Strufe. Siehe: Ring (CPU) |
S | System/User | S und Type geben zusammen den Typ des Segmentes an, das durch diesen Deskriptor beschrieben wird (s. u.) |
Type |
Deskriptor Typen
System-Deskriptoren
S | Type | Art des Deskriptors |
---|---|---|
0 (System) | 0000 | reserviert |
0001 | verfügbares 16-bit Task Status Segment (TSS) | |
0010 | Local Descriptor Table | |
0011 | benutztes 16-bit Task Status Segment (TSS) | |
0100 | 16-bit Call Gate | |
0101 | Task Gate | |
0110 | 16-bit Interrupt Gate | |
0111 | 16-bit Trap Gate | |
1000 | reserviert | |
1001 | verfügbares 32-bit TSS | |
1010 | reserviert | |
1011 | benutztes 32-bit TSS | |
1100 | 32-bit Call Gate | |
1101 | reserviert | |
1110 | 32-bit Interrupt Gate | |
1111 | 32-bit Trap Gate |
Ein "Call Gate"-Segmentdeskriptor beschreibt einen wohldefinierte Einsprungpunkt z. B. für Betriebssystemfunktionen. Call Gates sind im Protected Mode die einzige Möglichkeit für Code mit einer niedrigeren Privilegienstufe Code mit einer höheren Privilegienstufe aufzurufen.
In einem Task Status Segment werden bei einem Taskwechsel (bei Hardware-Multitasking) die Inhalte aller lokalen Register und weitere Statusinformationen automatisch gesichert.
User-Deskriptoren
Bei gesetztem S-Bit gibt das oberste Bit des Type-Feldes an, ob es sich um ein Code- oder Datensegment handelt. Die Bedeutung der übrigen 3 Bits ist bei Code- und Datensegmenten verschieden.
S | Type | Art des Deskriptors |
---|---|---|
1 (User) | 0EWA | Datensegment E – Expand Down W – Writable A – Accessed |
1CRA | Codesegment C – Conforming R – Readable A – Accessed |
Bedeutung der Bits:
- E
- Expand down – Die Segmentbasisadresse kennzeichnet das obere Ende des Segments, das Limit die Entfernung der unteren Grenze zur gegebenen Basisadresse. Dies ist für Stack-Segmente sinnvoll, da auf der x86-Plattform der Prozessorstack von oben nach unten befüllt wird.
- W
- Writable – in dieses Segment darf auch geschrieben werden.
- A
- Accessed – Wird vom Prozessor automatisch auf 1 gesetzt, wenn auf das Segment zugegriffen wurde. Es kann von dem Betriebssystem wieder auf 0 gesetzt werden.
- R
- Readable – Codesegment kann auch (als Daten) ausgelesen werden. Schreiben in Codesegmente ist generell nicht möglich.