Virtual 8086 Mode
Disclaimer
This guide is meant for people with very little experience. If you follow along and have a curious mind, this will teach you extremely important concepts in osdev.
Disclaimer
Due to the complex concepts and operations explained on this page, the code is intended for informational purposes only. Therefore, we cannot guarantee its actual functionality.
Guide Reference
This guide contain a part of the informations located in the CPU System Management Modes guide.
Virtual 8086 mode is a sub-mode of the Protected mode. When the CPU is in Virtual 8086 mode, it's running an "Emulated" 16-bit Real Mode machine.
Limitations
The limitations are:
- All the limitations of the Real Mode.
- You can't enter in Protected Mode, you need to switch back to the Protected Mode.
- Some stuff about the fact that the low level commands are emulated and not really executed as in the Real Mode, but is problems too technical to be important to us.
Advantages
The advantages are:
- We can use all the Real Mode functions, while we are in fact in Protected Mode.
Code example
[ORG 0x4000]
[BITS 32]
SEGMENT_VIRTUAL_8086_MODE equ 0x0000
enterVirtual8086:
push 0x0000 ; GS
push 0x0000 ; FS
push 0x0000 ; DS
push 0x0000 ; ES
push 0x0000 ; SS
push 0x7000 ; ESP
push dword (1<<17) | (1<<9) | (1<<1) | (3<<12) ; EFLAGS
push SEGMENT_VIRTUAL_8086_MODE ; CS
push startVirtual8086Mode ; EIP
iret
[BITS 16]
startVirtual8086Mode:
jmp $Explanation
[ORG 0x4000]
[BITS 32] ; We start in Protected ModeSEGMENT_VIRTUAL_8086_MODE equ 0x0000 ; The address of the segment
enterVirtual8086: ; We have to create the stack for the physical addressing
push 0x0000 ; GS
push 0x0000 ; FS
push 0x0000 ; DS
push 0x0000 ; ES
push 0x0000 ; SS starting point
push 0x7000 ; ESP - stack grows down from 0x0000:0x7000
push dword (1<<17) | (1<<9) | (1<<1) | (3<<12) ; Set EFLAGS
; bit 17 - VM | Activate Virtual 8086 Mode
; bit 9 - IF | Enable hardware interrupts
; bit 1 - Reserved | Must always be 1
; bits 12-13 - IOPL=3 | Allow in/out and cli/sti
push SEGMENT_VIRTUAL_8086_MODE ; CS (segment of entry point)
push startVirtual8086Mode ; EIP (entry point offset)
iret ; jump in VM86 mode[BITS 16] ; We're in Virtual 8086 Mode that's a 16-bits mode
startVirtual8086Mode:
jmp $