第3章 Windows运行机理-3.1 内核分析(10)

我们可以从SthVxD.c中看到CVxD_Dynamic_Init和CVxD_Dynamic_Exit这两个函数的定义。

ifdef _VxD_SERVICES

extrn _CVxD_Get_Version:near

endif

extrn _CVxD_V86API@12:near

extrn _CVxD_PMAPI@12:near

extrn C EnableHlt: dword

BeginProc CVxD_Control

Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,

CVxD_Dynamic_Init, sCall

Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT,

CVxD_Dynamic_Exit, sCall

Control_Dispatch W32_DEVICEIOCONTROL,

CVxD_W32_DeviceIOControl,

sCall, <ebp, ecx, ebx, edx, esi>

clc

ret

EndProc CVxD_Contro

这是一段消息处理函数。

当VxD初始化时,发生SYS_DYNAMIC_DEVICE_INIT的消息而转入CVxD_Dynamic_Init函数中进行处理。

W32_DEVICEIOCONTROL是宏来定义的,设备控制程序CVxD_W32_DeviceIOControl,<ebp, ecx, ebx, edx, esi>是调用函数时用来传递参数的寄存器的名字。CVxD_W32_DeviceIOControl是留给应用程序的接口函数。当VxD的应用运行后,它和VxD进行数据交换就通过此函数来实现。因为它是用汇编编写的,所以,所有的参数都使用寄存器来传递。

 接下来可以看见三个函数

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; 内核空闲(IDLE)时调用此函数

;;

;; 使用HLT指令可以降低CPU的温度

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BeginProc _IDLEHandleProc

mov eax,[EnableHlt]

test eax,eax

jnz NEXT  ;查看EnableHlt是否为真,当EnableHlt为真时

;(即允许用降温功能)转入NEXT

;当EnableHlt为假时,清去零标志位,返回系统中。

stc

ret

NEXT:

sti ;必须打开中断, 如果没有打开中断,CPU就不能响应中断,

;就会死机。当中断打开时,当运行HLT指令后,

;机器一直停止直到外部有一个中断。

;例如敲键或移动鼠标时,当中断处理写成后,

;会从下一条指令开始执行,就不会死在HLT指令处。

hlt ;CPU停机,停机就是使得CPU不工作,

;当CPU不工作时,CPU的功耗就很小,所以能降低温度

stc ;当有事件产生时,清去零标志位,

;返回系统中去处理其程序;

ret

EndProc _IDLEHandleProc

内核空闲(IDLE)时,调用_IDLEHandleProc函数,通过HLT指令达到降温

的目的。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; 安装内核空闲(IDLE)时调用的函数

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BeginProc _InstallIDLEProc

push esi

lea esi,[_IDLEHandleProc]

VMMCall Call_When_Idle

pop esi

mov eax,0

setnc al

ret

EndProc _InstallIDLEProc

_InstallIDLEProc函数是在SthVxD.c的CVxD_Dynamic_Init(void)的函数中

被调用的,当它被装入后,VMM空闲时,就自动地调用函数

_IDLEHandleProc。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; 取消安装内核空闲(IDLE)时调用的函数

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BeginProc _UnInstallIDLEProc

push esi

lea esi,[_IDLEHandleProc]

VMMCall Cancel_Call_When_Idle

pop esi

mov eax,0

setnc al

ret

EndProc _UnInstallIDLEProc

_UnInstallIDLEProc函数和_InstallIDLEProc函数一样,也是在SthVxD.c中被CVxD_Dynamic_Exit(void)函数调用的。它的作用是去掉VMM注册的空闲函数。

;**************************************************

; V86模式调用的入口

;

; 把调用转变成对C函数的调用, 以便于开发功能强大的处理能力

;

;**************************************************

BeginProc CVxD_V86

scall CVxD_V86API,

<[ebp].Client_EAX, [ebp].Client_EBX, [ebp].Client_ECX>

mov [ebp].Client_EAX,eax ; put return code

ret

EndProc CVxD_V86

;**************************************************

; 保护模式调用的入口

;

; 把调用转变成对C函数的调用, 以便于开发功能强大的处理能力

;**************************************************

BeginProc CVxD_PM

scall CVxD_PMAPI,

<[ebp].Client_EAX, [ebp].Client_EBX, [ebp].Client_ECX>

mov [ebp].Client_EAX,eax

ret

EndProc CVxD_PM

VxD_LOCKED_CODE_ENDS

以上CVxD_V86和CVxD_PM两个函数都在SthVxD.c中定义。它们是V86模式和保护模式调用的入口,其实,它们的代码分别为CVxD_V86API和CVxD_PMAPI。此处只有函数定义,没有具体的实现功能。

VxD不光可以给WIN32位程序调用,WIN16和DOS程序都可以调用VxD提供的功能,它们都通过中断2FH来调用,并设置相应的参数。保护模式与此也是一样的,不过要用到VxD的号码。

;*************************************************;

; 不是动态的VxD时,在Window启动时会被实模式调用

;

;**************************************************

VxD_REAL_INIT_SEG

BeginProc CVxD_Real_Init

xor bx, bx

xor si, si

xor edx, edx

mov ax, Device_Load_Ok

ret

EndProc CVxD_Real_Init

VxD_REAL_INIT_ENDS

END CVxD_Real_Init

以上是一段实模式的初始化调用的函数,主要是用在Windows 9x启动时。当Windows 9x启动时,就会调用到这个函数。这是一个实模式代码,可以看到代码段和寄存器是不同的。这不过是一个框架程序,它会将对汇编的调用全部转变成对C的调用。这样就很方便开发程序。

相关推荐
祈安_2 小时前
深入理解指针(七)
c语言·后端
m0_531237174 小时前
C语言-编程实例2
c语言·开发语言
zjxtxdy5 小时前
C语言(续)
c语言·开发语言
Navigator_Z5 小时前
LeetCode //C - 964. Least Operators to Express Number
c语言·算法·leetcode
m0_531237176 小时前
C语言-结构体进阶
c语言·开发语言
2501_918126917 小时前
stm32能做次声波检测器吗?
c语言·stm32·单片机·嵌入式硬件·学习
xiaoccii7 小时前
堆(顺序结构)
c语言
宫瑾8 小时前
VSCode使用C/C++ extensions开发STM32,添加头文件路径
c语言·c++·vscode
m0_531237178 小时前
C语言-编程实例
c语言·开发语言·数据结构