v86m_sup.s
来自「一个类似windows」· S 代码 · 共 176 行
S
176 行
/*
* FILE: ntoskrnl/ke/i386/vm86_sup.S
* PURPOSE: V86 mode support
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 09/10/00
*/
#include <ndk/asm.h>
.globl _Ki386RetToV86Mode
.globl _KiV86Complete
/*
* VOID Ki386RetToV86Mode(KV86M_REGISTERS* InRegs,
* KV86M_REGISTERS* OutRegs);
*
* Starts in v86 mode with the registers set to the
* specified values.
*/
_Ki386RetToV86Mode:
/*
* Setup a stack frame
*/
pushl %ebp
movl %esp, %ebp
/*
* Save registers
*/
pusha
/*
* Get a pointer to IN_REGS
*/
movl 8(%ebp), %ebx
/*
* Save ebp
*/
pushl %ebp
/*
* Save a pointer to IN_REGS which the v86m exception handler will
* use to handle exceptions
*/
pushl %ebx
/*
* Since we are going to fiddle with the stack pointer this must be
* a critical section for this processor
*/
cli
/*
* Save the exception handler stack from the TSS
*/
movl %fs:KPCR_TSS, %esi
pushl KTSS_ESP0(%esi)
/*
* The stack used for handling exceptions from v86 mode in this thread
* will be the current stack adjusted so we don't overwrite the
* existing stack frames
*/
movl %esp, KTSS_ESP0(%esi)
/*
* Create the stack frame for an iret to v86 mode
*/
pushl KV86M_REGISTERS_GS(%ebx)
pushl KV86M_REGISTERS_FS(%ebx)
pushl KV86M_REGISTERS_DS(%ebx)
pushl KV86M_REGISTERS_ES(%ebx)
pushl KV86M_REGISTERS_SS(%ebx)
pushl KV86M_REGISTERS_ESP(%ebx)
pushl KV86M_REGISTERS_EFLAGS(%ebx)
pushl KV86M_REGISTERS_CS(%ebx)
pushl KV86M_REGISTERS_EIP(%ebx)
/*
* Setup the CPU registers
*/
movl KV86M_REGISTERS_EAX(%ebx), %eax
movl KV86M_REGISTERS_ECX(%ebx), %ecx
movl KV86M_REGISTERS_EDX(%ebx), %edx
movl KV86M_REGISTERS_ESI(%ebx), %esi
movl KV86M_REGISTERS_EDI(%ebx), %edi
movl KV86M_REGISTERS_EBP(%ebx), %ebp
movl KV86M_REGISTERS_EBX(%ebx), %ebx
/*
* Go to v86 mode
*/
iret
/*
* Handle the completion of a vm86 routine. We are called from
* an exception handler with the registers at the point of the
* exception on the stack.
*/
_KiV86Complete:
/* Restore the original ebp */
movl TF_ORIG_EBP(%esp), %ebp
/* Get a pointer to the OUT_REGS structure */
movl 12(%ebp), %ebx
/* Skip debug information and unsaved registers */
addl $0x30, %esp
/* Ignore 32-bit segment registers */
addl $12, %esp
/* Save the vm86 registers into the OUT_REGS structure */
popl KV86M_REGISTERS_EDX(%ebx)
popl KV86M_REGISTERS_ECX(%ebx)
popl KV86M_REGISTERS_EAX(%ebx)
/* Restore the old previous mode */
popl %eax
movb %al, %ss:KTHREAD_PREVIOUS_MODE(%esi)
/* Restore the old exception handler list */
popl %eax
movl %eax, %fs:KPCR_EXCEPTION_LIST
/* Ignore the 32-bit fs register */
addl $4, %esp
popl KV86M_REGISTERS_EDI(%ebx)
popl KV86M_REGISTERS_ESI(%ebx)
popl KV86M_REGISTERS_EBX(%ebx)
popl KV86M_REGISTERS_EBP(%ebx)
/* Ignore error code */
addl $4, %esp
popl KV86M_REGISTERS_EIP(%ebx)
popl KV86M_REGISTERS_CS(%ebx)
popl KV86M_REGISTERS_EFLAGS(%ebx)
popl KV86M_REGISTERS_ESP(%ebx)
popl KV86M_REGISTERS_SS(%ebx)
popl KV86M_REGISTERS_ES(%ebx)
popl KV86M_REGISTERS_DS(%ebx)
popl KV86M_REGISTERS_FS(%ebx)
popl KV86M_REGISTERS_GS(%ebx)
/*
* We are going to fiddle with the stack so this must be a critical
* section for this process
*/
cli
/*
* Restore the exception handler stack in the TSS
*/
movl %fs:KPCR_TSS, %esi
popl KTSS_ESP0(%esi)
/* Exit the critical section */
sti
/* Ignore IN_REGS pointer */
addl $4, %esp
/* Ignore ebp restored above */
addl $4, %esp
/* Return to caller */
popa
movl %ebp, %esp
popl %ebp
ret
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?