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 + -
显示快捷键?