AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > 汇编语言

客户寄存器结构

51自学网 http://www.51zixue.net

记住,int 21h是一个DOS服务,因而其在V86模式下是可用的,我们如何在VxD中调用一个V86中断?一个方法是使用Exec_Int服务。这个VMM服务把要调用的中断号放在eax中。它模拟指定的中断然后返回到调用的VM。然而,它必须在一个嵌套执行块中被调用。嵌套执行块被Begin_Nest_V86_Exec (或 Begin_Nest_Exec)和End_Nest_Exec包括起来。如果我们要调用int 21h功能2h,我们需要在嵌套执行块内转换Client_Byte_Reg_Struc结构的Client_ah和Client_Dl,然后把值21h放在eax中。当一切准备好了,就调用Exec_Int。

例子:

例子是一个动态VxD,它调用int 21h的功能2使PC喇叭发声。

.386p
include /masm/include/vmm.inc
include /masm/include/vwin32.inc
include /masm/include/v86mmgr.inc
VxDName TEXTEQU
ControlName TEXTEQU
VxDMajorVersion TEXTEQU <1>
VxDMinorVersion TEXTEQU <0>

VxD_STATIC_DATA_SEG
VxD_STATIC_DATA_ENDS

VXD_LOCKED_CODE_SEG
;----------------------------------------------------------------------------
; Remember: The name of the vxd MUST be uppercase else it won't work/unload
;----------------------------------------------------------------------------
DECLARE_VIRTUAL_DEVICE %VxDName,%VxDMajorVersion,%VxDMinorVersion, %ControlName,UNDEFINED_DEVICE_ID,UNDEFINED_INIT_ORDER

Begin_control_dispatch %VxDName
Control_Dispatch W32_DEVICEIOCONTROL, OnDeviceIoControl
End_control_dispatch %VxDName

VXD_LOCKED_CODE_ENDS

VXD_PAGEABLE_CODE_SEG
BeginProc OnDeviceIoControl
assume esi:ptr DIOCParams
.if [esi].dwIoControlCode==1
Push_Client_State
VMMCall Begin_Nest_V86_Exec
assume ebp:ptr Client_Byte_Reg_Struc
mov [ebp].Client_dl,7
mov [ebp].Client_ah,2
mov eax,21h
VMMCall Exec_Int
VMMCall End_Nest_Exec
Pop_Client_State
EndI:
.endif
xor eax,eax
ret
EndProc OnDeviceIoControl
VXD_PAGEABLE_CODE_ENDS

end

讲解

Push_Client_State

这没什么好讲解的。当一个VxD接收到一个DeviceIoControl消息,ebp已经指向了当前VM的客户寄存器结构。我们调用Push_Client_State宏在堆栈中存储客户寄存器结构的状态。然后用Pop_Client_State宏恢复客户寄存器。

VMMCall Begin_Nest_V86_Exec

通过调用Begin_Nest_V86_Exec开始嵌套执行块。

assume ebp:ptr Client_Byte_Reg_Struc
mov [ebp].Client_dl,7
mov [ebp].Client_ah,2

改变在客户寄存器中的dl和ah寄存器的映象。这个改变的值将由中断使用。

mov eax,21h
VMMCall Exec_Int

Exec_Int要求在eax存有一个中断号。我们想使用int 21h。等会我们调用Exec_Int去模拟中断。

VMMCall End_Nest_Exec
Pop_Client_State

当Exec_Int返回,我们完成了嵌套执行块,并且由堆栈中恢复了客户寄存器结构的值。 你将听到你的PC喇叭发出一声响。

 
 

上一篇:虚拟8086模式的内存管理  下一篇:请求执行时间段与Shell函数