The reason is simple. Imagine if it were possible to enter Virtual 8086 mode by executing a POPFD instruction. Then there would be all sorts of problems, due to the old values stored in the segment registers not being appropriate for Virtual 8086 mode. Therefore, POPFD does not update the VM flag, and IRET must be used. IRET sets the VM flag based on bit 17 of the popped EFLAGS value. Note that when entering or leaving Virtual 8086 mode, the interrupt stack frame contains four additional DWORDs, with the values for the DS, ES, FS and GS registers in Virtual 8086 mode, respectively.
In Virtual 8086 mode, the TSS can contain an interrupt redirection bitmap if VME is enabled in CR4. This lets you specify whether a particular software interrupt number should cause a GPF exception or be handled using the IVT, as in real-address mode. Also, like always when running at CPL=3, the TSS contains the values of SS and ESP to load when transitioning to a higher privilege level due to an exception, as well as the I/O permission bitmap.
You leave Virtual 8086 mode by triggering an exception, for example with an INT instruction or an undefined opcode. For the same reason as above, you can't unset the VM flag using POPFD.
|