Learning Center
Plans & pricing Sign in
Sign Out

8086 emulation


									     8086 emulation

   Using Virtual-8086 mode to
execute real-mode procedures in
 a protected-mode environment
       Features of real-mode
• At power-up the Pentium begins executing
  in real-address mode (memory addressing
  does not require use of descriptor tables)
• CPU privilege restrictions are not imposed
• Memory addresses are limited to 20-bits
• Interrupt-routing is handled using the IVT
• Multitasking and paging are unsupported
• Lots of ‘legacy’ software exists for 8086
  Rationale for 8086 emulation
• It is desirable to run multiple 8086 tasks in
  an environment that ‘protects’ each task
  from interference by other tasks, yet offers
  each task the illusion of being in control of
  the system (as in ‘real-mode’ environment)
• Duplicate the environment of an 8086 cpu
• Synchronize access to shared resources,
  (such as files and peripheral i/o devices)
      The VM-bit in EFLAGS
• The CPU executes in ‘Virtual-8086’ mode
  when the VM-bit (bit #17) in EFLAGS is 1
• POPFD instruction cannot modify VM-bit
• Two methods for entering VM86-mode:
     1) use the IRETD instruction
     2) use a task-switch to a new 386 TSS
• The only way to leave VM86-mode is with
  an interrupt (either hardware or software)
  or by resetting the processor (i.e., reboot)
 Entering a VM86-mode procedure
                             Ring-0 Stack-Frame


Execute IRETD instruction
 while in protected-mode                ES-image
   at privilege-level 0                 SS-image


                            EFLAGS ( VM=1, NT=0 )


          SS:ESP                         IP-image
        I/O-sensitive Instructions
• While in VM86-mode, certain instructions are
  ‘sensitive’ to the current value of the IOPL-field
  in EFLAGS:
   –   The CLI and STI instructions
   –   The PUSHF and POPF instructions
   –   The PUSHFD and POPFD instructions
   –   The IRET and IRETD instructions
   –   The INT-nn instruction
• The above instructions with generate a General
  Protection Exception (INT-13) unless IOPL==3
Emulating I/O-sensitive instructions
• Suppose a task executing in VM86-mode tries to
  disable device-interrupts, using a ‘cli’ instruction
• If IOPL<3, this instruction will cause a GP-fault
  (exception 0x0D) with an error-code equal to 0
• The exception-handler can examine the opcode
  (using the saved CS:EIP address on its stack)
• If the opcode equals 0xFA (i.e., ‘cli’), then the
  handler can clear bit #9 in the saved EFLAGS
  image (i.e., the IF-bit), increment the saved EIP,
  then execute IRETD to resume the VM86 task
           When IOPL == 3
• A VM86-task executes at privilege-level 3
• If IOPL==3, then the VM86 task is allowed
  to execute all the IO-sensitive instructions
  (except INT-nn) without generating a fault
• If the VME-bit (bit #0) in Control Register 4
  is set to 1, Virtual Mode Extensions will be
  enabled, and then INT-nn instructions can
  also be executed without triggering a fault
 How to leave VM-8086 mode?
• In VM86-mode, certain instructions trigger
  a General Protection Fault regardless of
  the current value in EFLAGS’ IOPL-field
• One of these is the halt-instruction (‘hlt’)
• The GP fault-handler can examine the
  opcode that triggered the fault (using the
  saved CS:EIP address on its ring0 stack)
  and, if it is 0xF4 (i.e., ‘hlt’), can terminate
  the VM86 task, if that is what is desired
       IO-permission Bitmap
• For tasks that execute in VM86-mode, the
  ability to execute IN/OUT instructions can
  be controlled on a port-by-port basis, using
  a bitmap data-structure within the TSS
• The bitmap can be up to 8192 bytes long
  (one bit for each of the 65536 i/o ports)
• The CPU finds this bitmap by using the
  value at offset 0x66 within the TSS, which
  holds the bitmap’s starting TSS offset
Layout of the Task-State Segment

          I/O Permission



                           TSS Base-Address
              Trapping I/O
• If you do not want a VM86 task to directly
  perform I/O operations on a specific port,
  you can set that port’s bit within the bitmap
• For example, to prevent a VM86 task from
  reading mouse-data (io-port 0x60), just set
  bit #0x60 within that task’s io-permission
  bitmap: this will causes a GP-fault if the
  instruction ‘IN al, #0x60’ is encountered
   Demo-program: ‘tryvm86.s’
• This demo illustrates entering and leaving
  a Virtual-8086 procedure within a 386 task
  that is executing in protected-mode
• The procedure draws directly to video ram,
  changing all the characters’ attribute-bytes
  to a blue-colored background (‘turn_blue’)
• It executes with device-interrupts disabled
• It includes no ‘io-sensitive’ instructions
        In-class exercise #1
• Try modifying the ‘tryvm86.s’ demo -- to do
  something that’s much more interesting
• Replace the ‘turn_blue’ routine with code
  that would call ROM-BIOS services (via
  interrupt 0x10) to print a message at the
  current cursor location
• You will need to add code to the GP-fault
  handler that ‘emulates’ an ‘int-nn’ opcode
   Steps for ‘int-nn’ emulation
• Determine the interrupt’s ID-number
• Advance the saved IP-value by 2 bytes (to
  skip the emulated interrupt-instruction)
• Simulate the ‘push’ of FLAGS, CS, and IP
  onto the VM86 task’s ring3 stack
• Copy vector from IVT onto ring0 stack
• Clear IF and TF bits in the saved EFLAGS
• NOTE: You may need to block all device
  interrupts (by setting PIC mask registers)
            Emulating ‘int-nn’
         Ring-0 Stack     Stack


                 DS       FLAGS
                 ES         CS

                 SS         IP


           EFLAGS                  Real-Mode IVT
                 CS                   CS
                  IP                  IP
        In-class exercise #2
• Include a counter in your GP-fault handler
• Display the counter-value when finishing
• Then enable Virtual-Mode Extensions (by
  setting bit #0 in Control Register 4)
• Re-execute your demo – notice the new
  value of the GP-fault handler’s counter!

To top