The i/o-sensitive instructions An introduction to the software emulation of i/o-sensitive

advertisement
The i/o-sensitive instructions
An introduction to the software
emulation of i/o-sensitive
instructions in Virtual-8086 mode
Impact of IOPL in VM86 mode
• In virtual-8086 mode, if IOPL<3, then any
instructions which could alter the IF-bit in
the FLAGS register (Interrupt Flag) cause
a General Protection fault (Exception 0xD)
• This lets the Virtual-8086 Monitor control
the actual effect on the CPU Interrupt-Flag
• The Monitor can ignore the instruction (by
just skipping past it) or it can perform the
operation on behalf of the VM86 program
The six i/o-sensitive opcodes
•
•
•
•
•
•
•
CLI (Clear Interrupt flag)
STI (Set Interrupt flag)
PUSHF (Push Flags register to stack)
POPF (Pop stack to Flags register)
IRET (Return from Interrupt)
INT-n (Software Interrupt)
The 32-bit versions of these instructions are also
i/o-sensitive (e.g., PUSHFD / POPFD / IRETD )
Role of the VM86 Monitor
• The GP-fault handler may need to emulate
the actions of the CPU when i/o-sensitive
instructions trigger faults in VM86 mode
• CLI and STI are simplest to emulate: all
the Monitor needs to do is set or clear the
IF-bit (bit #9) in the image of the EFLAGS
register that the CPU saved on its ring-0
stack, and increment the image of IP by 1
Emulating ‘pushf’
• To emulate ‘pushf’ the cpu subtracts 2
from the SP-register’s image (to make
room for a new word of its ring-3 stack),
copies the saved FLAGS-register image
from the ring-0 stack to this new word on
its ring-3 stack, then add 1 to the IP image
to skip past the ‘pushf’ opcode byte
Emulating ‘popf’
• To emulate ‘popf’ the cpu copies the top
word from its ring-3 stack to the lower half
of the saved EFLAGS register-image on
its ring-0 stack, adds 2 to the SP-register’s
image (to discard the copied word), then
adds 1 to the IP image (to skip past ‘popf’)
Emulating ‘iret’
• To emulate ‘iret’ the cpu copies the three
topmost words from its ring-3 stack onto
the lower halves of the three doublewords
on its ring-0 stack which hold the images
of the EIP, CS, and EFLAGS registers,
adds 6 to the saved SP-register image (to
discard the three words just copied)
Emulating ‘int-n’
• Emulating ‘int-n’ is the most complex of the
i/o-sensitive instruction-emulations
• We discussed the steps involved during
our preceeding lecture (we conducted an
in-class exercise that implemented them)
• Our next slide briefly review those steps
Steps for ‘int-n’ emulation
• Add 2 to the IP register-image (to skip past int-n)
• Decrement the SP register-image by 6 (to make
room for 3 new words on the ring-3 stack), and
the copy saved IF, CS, and FLAGS registerimages from the ring-0 stack to these new ring-3
stack locations
• Use the interrupt ID-number (the second byte of
‘int-n’ instruction) to find the IVT entry, and copy
its two words to the ring-0 stack locations for IP
and CS, respectively
• Clear bits #8 and #9 of the EFLAGS image
Demo: ‘emulate.s’
• We have created a demo-program which
incorporates these six emulations that we
just discussed: CLI / STI, PUSHF / POPF,
and IRET / INT-n.
• But real-mode code for Pentium CPUs can
also include 32-bit i/o-sensitive instructions
(e.g., PUSHFD / POPFD, and IRETD)
• These all have the operand-size prefix
0x66 in front of their one-byte opcodes
In-class exercise #1
• Add emulations for these three additional
i/o-sensitive instructions:
• PUSHFD (0x66, 0x9C)
• POPFD (0x66, 0x9D)
• IRETD (0x66, 0xCF)
• You will need to include some code in your
VM86 procedure to ‘test’ your emulations
In-class exercise #2
• Our emulation for ‘sti’ actually enables the
receipt of device interrupts by the CPU
• But we don’t provide interrupt-handlers!
• This could easily cause a program crash
• A ‘solution’ would be to ‘reflect’ any such
interrupts to the real-mode ROM-BIOS
interrupt-handlers (similar to emulating
software interrupts)
• So add this capability to your ‘emulate.s’
Download