x86-Programmierung und -Betriebsarten (Teil 4)

Das IOPL-Flag

Der Wert dieses Flags gibt die Privilegierungsstufe an, die ein Code-Segment mindestens aufweisen muss, um auf den I/O-Adressraum zugreifen zu können, das heißt es muss gelten CPL kleiner-gleich IOPL. Ist der CPL des aktuellen Tasks größer (niedrigere Privilegierungsstufe), so führen die I/O-Befehle IN, OUT, INS und OUTS zu einer bereits hinlänglich bekannten Exception "allgemeiner Protection-Fehler", was unter Windows sicher schon fast jedem Anwender als Schutzverletzung begegnet ist. Vernünftige Anwendungsprogramme unter einem "richtigen" Betriebssys

tem führen solche Zugriffe ausschließlich über das Betriebssystem aus. Weniger vernünftige Anwendungsprogramme versuchen das direkt, um einerseits die Performance zu erhöhen oder andererseits bestimmte Komponenten überhaupt ansprechen zu können. Neben den vier bereits erwähnten I/O-Befehlen sind auch CLI und STI vom IOPL-Flag abhängig. Diese sechs Befehle werden als IOPL-sensitive Befehle bezeichnet, da der Wert des IOPL-Flag einen Einfluss auf ihre Ausführung hat.

Sinn und Zweck dieser Einschränkung werden sofort einsichtig, betrachtet man den Fall, dass eine Systemfunktion beispielsweise einen Datensatz von der Festplatte liest, dabei durch einen Task-Switch unterbrochen wird und der neu aufgerufene Task durch einen unmittelbaren Zugriff auf die Steuerregister im Controller "dazwischenfunkt". In welchem Zustand sich die unterbrochene Systemroutine nach einem erneuten TaskSwitch befindet, ist völlig unvorhersehbar, der PC verabschiedet sich oder zerstört sogar Daten.

Ein Task kann das IOPL-Flag nur über die Befehle POPF (POP Flags) und PUSHF (PUSH Flags) verändern. Zur Änderung des IOPL-Flags steht kein expliziter Befehl zur Verfügung (wie zum Beispiel CLI oder STI für das Interrupt-Flag). Die beiden genannten Befehle POPF und PUSHF sind jedoch privilegiert, das heißt sie können nur von einem Code-Segment mit CPL=0 ausgeführt werden. Diese Stufe ist üblicherweise dem Betriebssystem-Kernel vorbehalten - die Anwendungsprogramme können das IOPL-Flag nicht verändern. Bei einem solchen Versuch löst der Prozessor eben eine Exception "allgemeiner Protection-Fehler" aus. Da die Flags jedoch Teil des TSS sind und sich somit von Task zu Task unterscheiden können, ist es durchaus möglich, dass ein Task Zugriff auf den I/O-Adressraum besitzt, ein anderer dagegen nicht.

Diese Strategie der globalen Absicherung des I/O-Adressbereichs über das IOPL-Flag ist bereits beim 80286 implementiert. Die nachfolgenden CPUs können die Ports zusätzlich individuell schützen. Diese Schutzstrategie für die Ports ist insbesondere im Hinblick auf den Virtual-8086-Mode implementiert worden.