Intel Prozessoren kennen drei Gruppen von Ereignissen, die einen Interrupt auslösen können:
Alle drei Interrupts basieren auf dem gleichen Mechanismus:
Wenn ein Interrupt auftritt, legt der Prozessor die Register CS:EIP und das aktuelle Flagregister auf den Stack. Anschließend führt er einen Sprung zu einer Interrupt-Behandlungsroutine aus. Die Adresse dieser Interruptroutine wird dabei einem Gate der Interrupt Deskriptor Tabelle (IDT) entnommen. Da der Prozessor maximal 256 Interrupt-Nummern kennt, kann die IDT maximal 256 Deskriptoren enthalten. Die Interrupt-Nummern 0 bis 31 hat Intel für den Prozessor selbst reserviert, die Nummern 32 bis 255 stehen dem Betriebssystem zur Verfügung. Abb. 2.12 stellt den Zusammenhang zwischen Interrupt-Nummern, der IDT und der GDT (bzw. der momentan aktiven LDT) dar.
Abb. 2.12: Bildung der Einsprungsadresse in eine
Interrupt-Behandlungsroutine (Interrupt-Gate)
Hardware-Interrupts (durch externe Ereignisse ausgelöst)
lassen sich in zwei Gruppen einteilen, in maskierbare und nicht
maskierbare Interrupts, sogenannte NMI's ("non maskable interrupt").
Auf NMI's reagiert der Prozessor immer mit einer Routine, die
mit dem Interrupt-Deskriptor 2 verbunden ist.
Im Gegensatz zu maskierbaren Interrupts sind NMI's nicht vom Status
des IF-Flags abhängig.
Tritt ein maskierbarer Interrupt auf und ist das IF-Flag gesetzt,
erwartet der Prozessor als nächstes die Interrupt-Nummer
auf dem Datenbus und interpretiert sie als Selektor in der IDT.
Die im Gate-Deskriptor festgelegte Privilegstufe wird bei Hardware-Interrupts
nicht beachtet.
Software Interrupts werden durch den INT-Befehl ausgelöst, wobei die Interrupt-Nummer direkt im Befehl enthalten ist. Software Interrupts lassen sich nicht maskieren und sind nicht vom Status des IF-Flags abhängig. Im Gegensatz zu Hardware-Interrupts wird bei INT-Befehlen eine Prüfung der Privilegstufe vorgenommen. Um einen bestimmten Software-Interrupt ausführen zu können, muß die aktuelle Privilegstufe (CPL) mindestens gleich privilegiert sein, wie die im Interrupt-Gate festgehaltene Privilegstufe (DPL). Diese Überprüfung hat zur Folge, daß nicht alle Anwendungen alle verfügbaren Interrupts benutzen können.
Exceptions sind in drei Gruppen aufgeteilt (Vgl. Tabelle 2.4).
Name | Grund für Auslösung | Beschreibung |
---|---|---|
Trap | Fehler tritt während der Befehlsausführung auf | CS:EIP (auf dem Stack) zeigen auf den Befehl, der dem problematischen Befehl unmittelbar folgt |
Fault | Prozessor erkennt einen Fehler bereits vor der Ausführung des fehlerhaften Befehls | CS:EIP (auf dem Stack) zeigen auf den Befehl, der die Exception ausgelöst hat (damit besteht die Möglichkeit, nach der Fehlerbeseitigung den Befehl zu wiederholen) |
Abort | schwerer Fehler, keine Aufnahme des entsprechenden Prozeßes mehr möglich | der auslösende Befehl kann nicht identifiziert werden, Prozeßabbruch |
Zusätzlich zur Fehleradresse (CS:EIP) legt der Prozessor bei bestimmten Exceptions einen Fehlercode auf dem Stack ab. Dieser Fehlercode gestattet es dem jeweiligen Exception-Handler, eine genauere Fehleranalyse durchzuführen. Bei diesem Fehlercode handelt es sich um einen Selektor auf einen Deskriptor, der das Segment beschreibt, in dem der Fehler aufgetreten ist. Abb. 2.13 stellt den Aufbau des Exception-Fehlercodes dar.
Abb. 2.13: Exception-Fehlercode
Soll der Prozessor nach Ausführung einer Exception, bei der ein Fehlercode auf dem Stack abgelegt wurde, das unterbrochene Programm fortsetzen, so muß dieser Fehlercode vor (!) dem Rücksprung (mittels IRET) vom Stack entfernt werden. Tabelle 2.5 gibt einen Überblick über alle möglichen Exceptions der 80386 und 80486 Prozessoren.
Einige der in Tabelle 2.5 genannten Exceptions sollen im folgenden näher betrachtet werden.
Interrupt 3: Haltepunkt (Trap)Interrupt 3 wird von Debuggern verwendet, um Software-Haltepunkte festzulegen. Das besondere am Interrupt 3 ist die Codierung des INT 3 Befehls, der im Gegensatz zu allen anderen Interrupt-Befehlen der Form: INT n in nur einem Byte codiert wird (0CCh). Damit wird ein Debugger in die Lage versetzt, an jeder beliebigen Stelle des zu untersuchenden Programms einen Breakpoint zu setzen und die entsprechenden Ausgaben und Tests im entsprechenden Interrupt 3 Exception Handler durchzuführen.
Interrupt 8: Doppelfehler (Abort, Errorcode)Normalerweise behandelt der Prozessor Exceptions, die während (!) einer Exception-Behandlung auftreten, vorrangig. Ist das aufgrund der Schwere der Exception nicht möglich, wird Interrupt 8 ausgelöst. Tabelle 2.6 listet alle Exception-Kombinationen auf, die zu einem Doppelfehler führen.
Erster Interrupt | Doppelfehler, wenn gefolgt von |
---|---|
0 | 0, 9, 10, 11, 12, 13 |
9 | 0, 9, 10, 11, 12, 13 |
10 | 0, 9, 10, 11, 12, 13 |
11 | 0, 9, 10, 11, 12, 13 |
12 | 0, 9, 10, 11, 12, 13 |
13 | 0, 9, 10, 11, 12, 13 |
14 | 0, 9, 10, 11, 12, 13, 14 |
Interrupt 13 wird bei Zugriffsverletzungen ausgelöst, die durch keine anderen Exceptions abgedeckt werden. Dazu gehören beispielsweise Speicherzugriffe auf schreibgeschützte Code- oder Datensegmente, Speicherzugiffe auf Segmente höherer Privilegstufe oder die Überschreitung der Segmentgrenzen.
Das in Assembler geschriebene Beispielprogramm pm_02.asm stellt die Weiterentwicklung des Beispiels aus Abschnitt 2.3 Einschalten des Protected Mode dar. Die Ausgabe des Programmes ist dieselbe wie im vorangegangenen Beispiel. Das Programm definiert jetzt jedoch eine IDT und stellt für alle möglichen Exceptions (0..17) eine eigene Routine zur Verfügung. Tritt eine Exception auf, wird die Exception-Nummer sowie ihr Name zusammen mit den letzten Werten der allgemeinen Register auf dem Bildschirm ausgegeben, der Prozessor in den Realmode zurückgeschaltet und das Programm beendet. Damit ist das Beispiel für Experimente geeignet. So könnte beispielsweise versucht werden, einen nicht definierten Deskriptor anzusprechen oder auf ein Segment zuzugreifen, das schreibgeschützt ist, um so eine Exception auszulösen. Welche Exception wird dabei ausgelöst? |