Interruptvektor
Der Interruptvektor ist in einem Computersystem diejenige Programmadresse, an die beim Auftreten eines Hard- oder Software-Interrupts oder einer Ausnahmesituation gesprungen wird.[1] Dort steht die Interrupt Service-Routine (ISR), die den Interrupt beantwortet. Jede Interruptquelle hat einen eigenen Interruptvektor, um mit einer jeweils unterschiedlichen ISR die spezifische Reaktion auf den Interrupt ausführen zu können. Ein spezieller Interruptvektor ist der Resetvektor, welcher auf den ersten nach einem Reset auszuführenden Befehl zeigt.
Interruptvektortabelle
Der Ort, von dem die Interruptvektoren gelesen werden, ist bei jedem Prozessortyp unterschiedlich und genau festgelegt. Meistens sind die Vektoren in einer Tabelle im RAM untergebracht, was eine größere Flexibilität bei der Manipulation der Sprungadressen erlaubt. Es gibt aber auch Prozessoren, bei denen die Interruptvektoren fest verdrahtet sind (z. B. bei PICmicro), oder Systeme, bei denen während des Interrupt-Acknowledge-Zyklus der Vektor aus einem Peripheriebaustein geholt wird.
Die Interruptvektortabelle (IVT) eines größeren Betriebssystems ist eine zentrale Struktur, die vor unerlaubtem Zugriff gut geschützt sein muss.
x86
Beim x86-Prozessor liegt die Interruptvektortabelle im Real Mode meist an der Adresse 0x00000000 und hat 256 Einträge zu je 32-bit (CS,IP). Somit braucht die CPU zum Auffinden der Adresse des gesuchten Interrupthandlers nur die Interruptnummer mit 4 zu multiplizieren, um den Offset zur Basisadresse zu erhalten. Aus den dort vorhandenen 4 Byte kann sie dann Segment- und Offsetadresse des Handlers berechnen.
Ab dem 80286 verfügt die CPU über ein eigenes Register – IDTR (Interrupt Descriptor Table Register) –, welches die physikalische Basisadresse und Länge der IVT enthält. Das IDTR wird auch im Real Mode verwendet, so dass eine andere Position des IVT im Real Mode theoretisch möglich ist. Aus Gründen der DOS-Kompatibilität wird aber auf ein Verschieben der IVT im Real Mode meist verzichtet.[2]
Im Protected Mode kann die Tabelle an eine beliebige Stelle im Adressbereich gelegt werden und enthält bis zu 256 Interrupt-Descriptoren, die neben der Sprungadresse noch weitere Informationen und Prioritätsangaben enthalten. Bei unerlaubten Prozessorzuständen oder bei Rechenfehlern werden die in der Interruptvektortabelle enthaltenen Exceptionvektoren gelesen und angesprungen.
IA-32
In der IA-32 gibt es von der Betriebsart abhängige Tabellen. Im Real Mode, in dem der Prozessor startet, liegt diese ab der Speicheradresse 0x00000000 und hat eine Länge von 1024 Byte. Der Prozessor hat insgesamt 256 Interrupts und jeder Vektor ist 4 Byte groß. Ein Vektor setzt sich aus einer Segmentadresse und einem Offset zusammen, die beim Aufruf in die CS- und IP-Register geladen werden.
Im Protected Mode kann die Interrupttabelle (welche hier Interrupt Descriptor Table heißt) an beliebiger Stelle im Speicher liegen. Die Lage wird mittels der CPU-Befehle LIDT und SIDT über das IDT-Register festgelegt bzw. ausgelesen, in dem die physikalische Startadresse, sowie die Länge der Tabelle angegeben wird. Jeder Eintrag ist 8 Byte groß, somit beträgt die Maximalgröße der Tabelle 2048 Byte. Die Einträge unterscheiden sich vom Real Mode, da es sich um IA-32-spezifische Deskriptoren handelt. Diese zeigen als Trap- oder Interrupt-Gate auf einen Selektor für ein Codesegment, sowie enthalten eine Offsetadresse für dieses Segment oder verweisen auf ein Task Status Segment, eine Datenstruktur, in der der komplette Zustand eines Programmes abgelegt ist (Werte für alle Register usw.). Aufgerufen werden die Einträge der Vektortabellen über Prozessor-interne Fehler (Einträge 0 bis 31) über eine externe Verschaltung, die eine Vektornummer an den Prozessor sendet oder von den Software im laufenden Programm.
8080/8085/Z80
Bei diesen Prozessoren gibt es 8 Interrupts. Die Einsprungadressen sind festgelegt und errechnen sich aus einer Multiplikation des Vektors mit 8 (d. h. 00hex bis 38hex). Nach einem Reset beginnen die Prozessoren mit der Programmausführung bei 00hex, was zeitgleich dem Vektor 0 entspricht. Aufgerufen werden können die Interrupts durch externe Anforderung – dabei sendet dann das Bauteil den entsprechenden Opcode (C7hex bis FFhex) an den Prozessor.
Der 8085 hat als Nachfolger des 8080 ein erweitertes Interruptsystem. Dort gibt es 3 externe Anforderungsleitungen, die direkt mit einer Einsprungadresse verknüpft sind. Es handelt sich dabei um 5.5, 6.5 und 7.5. Die Einsprungadressen liegen dabei mittig zwischen den 8080-Einsprungadressen: 5.5 auf 2Chex, 6.5 auf 34hex und 7.5 auf 3Chex.
Der Z80 bekam als Erweiterung des 8080 einen NMI (non maskable interrupt). Dessen Einsprungadresse liegt fest auf 66hex. Nach einem Reset befindet sich der Prozessor in einem zum 8080 kompatiblen Interruptmodus. Über Software kann man in zwei andere Interrupt-Modi wechseln. Im Modus IM1 wird bei externen Interruptanforderungen immer auf den Vektor 7 gesprungen (38hex). Im Mode IM2 lässt sich eine 256 Byte lange Interrupttabelle mit 128 Einsprungadressen erstellen. Dazu wird in das Prozessorregister I Bit 15 bis 8 der Startadresse dieser Tabelle eingetragen. Die interruptauslösende Baugruppe liefert dann Bit 7 bis 1. Der Prozessor liest dann die Speicherzelle [100hex × I + V] und [100hex × I + V + 1] aus, die die Startadresse der Interrupt-Service-Routine darstellt.
68K
Dieser Prozessor unterstützt 256 Interrupts, deren Startadressen in einer Tabelle abgelegt sind. Die Basisadresse ist im Vector-Base-Register abgelegt, zu der dann das Vierfache der Interruptnummer addiert wird.
Resetvektor
Der Hardware-Reset ist ein spezieller nicht maskierbarer Interrupt, der ein laufendes Programm unterbricht und gleichzeitig die Register zurücksetzt. Auch für ihn gibt es einen Vektor, den Resetvektor. Es ist diejenige Programmadresse, an die nach dem Power On Reset bzw. Hardware-Reset gesprungen wird. Da direkt nach dem Reset noch keine RAM-Inhalte zur Verfügung stehen, ist der Resetvektor immer im Festwertspeicher ROM des Systems abgelegt. Beim 8086 ist das die Adresse FFFF:0000, ab dem 80286 ist es F000:FFF0. Ein sich auf den Adressen FFFF0...FFFF4 üblicherweise befindender Intersegment-Sprungbefehl führt bei beiden Prozessoren zu identischem Verhalten.
C:\>debug -u f000:fff0 F000:FFF0 EA5BE000F0 JMP F000:E05B F000:FFF5 3033 XOR [BP+DI],DH F000:FFF7 2F DAS F000:FFF8 3137 XOR [BX],SI F000:FFFA 2F DAS F000:FFFB 3038 XOR [BX+SI],BH F000:FFFD 00FC ADD AH,BH F000:FFFF C430 LES SI,[BX+SI]
Bei anderen Prozessoren ist es oft die Adresse 0 (0x0000).
Verschiedenes
Für jeden nicht-maskierten Interrupt muss ein Interruptvektor und eine ISR existieren, sonst wird beim Auftreten des Interrupts eine ungültige Adresse angesprungen. Daher ist es eine der ersten Aktionen des Betriebssystems nach Reset, die Interruptvektortabelle aufzubauen und die Interrupt Service-Routinen zu installieren, um anschließend die Interrupts zu erlauben (Interrupt-Enable-Flag).
Etymologie
In älteren Schriften bezeichnet der Ausdruck "Interruptvektor" die ganze Interruptvektortabelle.[3] Dabei deckt sich die Bedeutung des Worts mit der des Vektors im mathematischen Sinn – also einem eindimensionalen Feld von Zahlen.
Einzelnachweise
- Hans-Peter Messmer und Klaus Dembowski: PC-Hardwarebuch, 7. Auflage, Addison-Wesley, 2003, Seite 155
- Tom Shanley: Protected Mode Software Architecture, MindShare Inc., 1996, Seite 41
- https://encyclopedia2.thefreedictionary.com/interrupt+vector