Prozessoren ab dem 80386 können im sogenannten V86-Modus einen, aber auch mehrere 8086-Prozessoren emulieren. Die Anzahl der dabei emulierten Prozessoren ist fast ausschließlich von der Menge des verfügbaren Speicherplatzes abhängig. Im V86-Modus verarbeitet der Prozessor Befehle wie im Realmode, d.h. Adressen werden wieder über eine Segment:Offsetadresse gebildet. Damit sind Segmentgrenzen wieder konstant 64 KB und unterschiedlich privilegierte Routinen existieren auch nicht mehr. Das ist zumindest aus der Sicht des ausgeführten Programmes so, denn im Hintergrund bleibt die Speicherverwaltung und (wenn es genutzt wird) das Paging des Protected Mode weiterhin aktiv.
Da für jeden Task festgelegt werden kann, ob er im V86-Modus oder im "normalen" Protected Mode ausgeführt wird, ist es möglich, mehrere V86-Tasks quasi-parallel, unter Kontrolle eines im Protected Mode laufenden Überwachungsprogramms ablaufen zu lassen. Wird dabei das Paging des Prozessors genutzt, können sogar mehrere Realmode Betriebssysteme (z.B. DOS) ausgeführt werden. Dabei "sieht" jeder 8086 Prozeß nur seinen 1MB großen Realmode-Adressraum, der sich aber aufgrund der Anwendung des Paging-Mechanismus überall im adressierbaren Speicherbereich (4 GByte) befinden kann.
Umschaltung in den V86-ModusDer Zustand des Bit 17 (VM-Bit "Virtueller 8086-Modus") im (E)FLAG-Register entscheidet darüber, ob ein Prozeß im virtuellen 8086-Modus oder im Protected-Mode ausgeführt wird. Da Anwendungen den Zustand des VM-Bits nicht verändern können und Befehle, die das Flagregister verändern (PUSHF, POPF), das VM-Bit nicht beeinflussen, kann nur ein Task-Wechsel oder ein Interrupt-Return den Zustand des VM-Bits neu festlegen. Aus diesem Grund ist der virtuelle 8086-Modus an die Ausführung von Tasks gebunden.
Ist das VM-Bit im FLAG-Register des momentan laufenden Prozesses gesetzt (1), dann interpretiert der Prozessor Befehle so, als ob er sich im Realmode befinden würde. V86-Tasks werden immer in der niedrigsten Privilegstufe (3) ausgeführt und unterliegen damit allen Kontrollmechanismen, die dem Prozessor zur Verfügung stehen. So lösen Zugriffsversuche auf spezielle Protected Mode Register (CR0, GDTR, usw.) Exceptions aus, die die Initialisierung des Protected Mode unterbinden (Was auch nicht möglich sein darf, da der Protected Mode in der Form des V86-Modus im Hintergrund bereits aktiv ist).
Protected Mode UtilitiesDer V86-Modus eignet sich besonders zur Implementation von Protected-Mode-Utilities. Dazu gehören beispielsweise EMS-Emulatoren oder Multitasker für DOS. Dabei wird DOS selbst als eine V86-Anwendung betrachtet und von einem im Protected Mode laufendem Überwachungsprogramm kontrolliert. Für DOS "sieht" es so aus, als befindet es sich auf einem "normalen" Rechner mit 8086 Prozessor bzw. im Realmodus.
EMS-Emulatoren (EMM386.EXE)Auf Rechnern mit 8086 bzw. 80286 Prozessoren wurde Expanded Memory in Form einer Speichererweiterungskarte bereitgestellt. Dabei sorgte ein Gerätetreiber für die problemlose Kommunikation zwischen Anwendungsprogrammen und dem Erweiterungsspeicher. Bei diesem Verfahren konnten 16 KByte große Speicherseiten in den 1MB großen Realmode-Adressbereich eingeblendet werden.
Ab dem 80386 kann DOS im V86-Modus ausgeführt werden, wobei es einem im Hintergrund laufendem Virtual-Control-Programm (z.B. EMM386.EXE) möglich ist, über den Paging-Mechanismus Speicherseiten aus dem Extended Memory (oberhalb der 1MB Grenze) in den Realmode-Bereich einzublenden. Dabei wird der Speicher vom Realmodeprogramm auf die gleiche Weise angesprochen, wie es bei der Nutzung einer Erweiterungsspeicherkarte möglich ist. Programme, die EMS nach dem LIM-Standard anfordern (Vgl. 1.3.3 EMS / XMS), können so auf relativ einfache Weise mit Expanded Memory versorgt werden.
DOS-MultitaskerDa der Prozessor in der Lage ist, mehrere V86-Prozesse zu verwalten, ergibt sich auch die Möglichkeit, mehrere Betriebssysteme bzw. mehrere 8086-Anwendungen parallel ablaufen zu lassen. Die Überwachung und Steuerung der einzelnen Prozesse übernimmt, ähnlich wie bei EMS-Emulatoren, ein im Protected Mode laufendes Überwachungsprogramm.
Dabei hat das Überwachungsprogramm allerdings mit einigen Problemen zu kämpfen, da sich DOS-Programme in der Regel nicht sehr kooperativ gegenüber anderen Programmen zeigen. So schreiben viele DOS-Programme direkt in das Video RAM, reservieren den gesamten verfügbaren Speicher oder programmieren den Interrupt-Controller um.
Da die Hardware aber nur einmal vorhanden ist, kann auch immer nur ein Prozeß darauf zugreifen, um z.B. über die parallele Schnittstelle einen Text auszugeben. Aufgabe des Kontrollprogrammes ist es, die einzelnen V86-Prozesse untereinander zu koordinieren, um die parallele Ausführung zu gewährleisten. Obwohl das Problem des Speicherzugriffs über den Paging-Mechanismus auf relativ einfache Weise zu lösen ist, existieren weitere Probleme, die durch I/O Zugriffe oder Speicherbereiche für bestimmte Peripheriegeräte (z.B. das Video RAM) ausgelöst werden.
Letzteres Problem läßt sich z.B. auch über das Paging lösen. Indem in der Paging-Tabelle des jeweiligen V86-Prozesses die Speicherseiten des Video-RAMs als nicht präsent markiert werden ("present"-Bit 0), kann ein Zugriffsversuch auf die entsprechende Seite über eine Exception abgefangen werden und der Speicherzugriff auf einen Buffer des Kontrollprogramms durchgeführt werden. Das Kontrollprogramm entscheidet dann über die Ausgabe der Daten.
Das Problem der I/O Portzugriffe ist im Gegensatz dazu nicht so einfach zu lösen. Zwar kann über die I/O Permission Bitmap des zum V86-gehörigen TS-Segmentes der Zugriff auf bestimmte Portadressen eingeschränkt werden, jedoch wird dadurch auch die Lauffähigkeit einer Vielzahl von Programmen (die z.B. im Grafikmodus arbeiten) unterbunden. Portzugriffe müssen deshalb unter den einzelnen Programmen koordiniert werden. Um dieses Problem zu lösen, können z.B. die folgenden Möglichkeiten benutzt werden:
Die erste Möglichkeit kann angewendet werden, wenn nur ein V86-Task läuft (z.B. DOS mit EMS-Emulator). Die zweite Möglichkeit hat den Nachteil, viel Zeit mit der Bearbeitung von Exceptions zu verbrauchen. Ein Programm, das eine Seite über die Druckerschnittstelle ausgeben möchte, müßte mehrere tausend Exceptions über sich ergehen lassen, die viel Zeit kosten (Task-Wechsel, Sichern aller Register, Überprüfung der Privilegstufen, Auswerten der Exception, usw.).
Viele Überwachungsprogramme gehen deshalb so vor: Grundsätzliches
Sperren aller Ports für den ausgeführten Prozeß
und exklusives Freigeben des gewünschten Ports bei der ersten
Benutzung durch einen Task. Dieser Port ist für die Zeit
der Benutzung durch den Task für alle anderen gesperrt.
Neben dem aktiven Task existiert also auch ein "aktiver Augabetask".
Auf diese Weise ist es möglich, daß ein Programm im
Hintergrund einen Text auf einem Drucker ausgibt, während
ein anderes Programm Daten über eine serielle Schnittstelle
empfängt.