国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

羅云彬VxD教程--虛擬8086模式的內(nèi)存管理

2019-11-17 05:34:07
字體:
供稿:網(wǎng)友

  下邊我們用到的V86即指虛擬8086模式。 在以前的教程中,你學(xué)習(xí)了怎樣模擬V86中斷,但還有一個(gè)問題沒有解決:在VxD和V86代碼之間交換數(shù)據(jù)。我們將在此學(xué)習(xí)如何使用V86內(nèi)存治理器來實(shí)現(xiàn)這個(gè)功能。在這里下載例子程序

理論

假如你的VxD和一些V86程序一起運(yùn)行,如何傳送大量數(shù)據(jù)到V86程序中或從V86程序中傳送大量數(shù)據(jù)遲早是一個(gè)大問題。通過寄存器傳送大量數(shù)據(jù)是不現(xiàn)實(shí)的??赡苣愕南乱粋€(gè)想法是在ring0中分配一大塊內(nèi)存,并且通過一些寄存器傳送其指針到V86程序,使其能訪問這些數(shù)據(jù)。假如你這樣做,可能會(huì)破壞你的系統(tǒng),因?yàn)閂86的地址定位方式需要segment:offset對(duì),而不是線性定位方式。對(duì)這個(gè)問題,有很多解決的方法。然而,我選擇了一個(gè)由V86內(nèi)存治理器提供的一種簡(jiǎn)便的方法。

如你能在你可使用的V86內(nèi)存范圍內(nèi)找到一個(gè)空閑的內(nèi)存塊作為通訊緩沖區(qū),這將解決其中的一個(gè)問題。然而,指針傳送的問題依然存在。你可以通過V86內(nèi)存治理器的服務(wù)來解決這兩個(gè)問題。V86內(nèi)存治理器是為V86應(yīng)用治理內(nèi)存的靜態(tài)VxD。它還為V86應(yīng)用提供EMS和XMS服務(wù)和為其他VxD提供API傳送服務(wù)。API傳送是一個(gè)從ring0拷貝數(shù)據(jù)到V86范圍內(nèi)的緩沖區(qū)并且傳送V86緩沖區(qū)地址到V86代碼的過程。V86內(nèi)存治理器有一個(gè)在V86內(nèi)存范圍內(nèi)的傳送緩沖區(qū),其含有VxD拷貝到V86內(nèi)存范圍內(nèi)的數(shù)據(jù),反之亦然。初始的緩沖區(qū)是4K。你以調(diào)用V86MMGR_Set_Mapping_Info來增加它的大小。

現(xiàn)在你知道了傳送緩沖區(qū),我們?nèi)绾慰饺牖蚩匠鰯?shù)據(jù)呢?這個(gè)問題通過調(diào)用兩個(gè)服務(wù)來解決:V86MMGR_Allocate_Buffer和V86MMGR_Free_Buffer。

V86MMGR_Allocate_Buffer從傳送緩沖區(qū)分配一塊內(nèi)存并且從ring0拷貝一些數(shù)據(jù)到分配的V86緩沖區(qū)。V86MMGR_Free_Buffer正好相反:它從分配的V86內(nèi)存塊拷貝一些數(shù)據(jù)到ring0緩沖區(qū)并且釋放由V86MMGR_Allocate_Buffer分配的內(nèi)存塊。

記住,V86在內(nèi)存治理器象堆棧一樣治理被分配的緩沖區(qū)。這意味著分配/釋放必須按先進(jìn)后出的規(guī)則。所以如你調(diào)用了兩次V86MMGR_Allocate_Buffer,第一個(gè)V86MMGR_Free_Buffer將釋放由第二個(gè)V86MMGR_Allocate_Buffer調(diào)用而分配的緩沖區(qū)。

我們來看一下V86MMGR_Allocate_Buffer的定義,它是一個(gè)基本寄存器傳送參數(shù)的服務(wù)。

EBX 當(dāng)前VM的句柄
EBP 指向當(dāng)前VM的客戶寄存器結(jié)構(gòu)的指針
ECX 從傳送緩沖區(qū)分配的字節(jié)數(shù) CARRY FLAG 進(jìn)位標(biāo)志位,如你不想從ring0緩沖區(qū)拷貝數(shù)據(jù)到分配的內(nèi)存塊就清零, 如你想從ring0緩沖區(qū)拷貝數(shù)據(jù)到分配的內(nèi)存塊就置1
FS:ESI 指向ring0緩沖區(qū)的selector:offset指針,緩沖區(qū)中有要被拷貝到被分配的 緩沖區(qū)中的數(shù)據(jù)假如進(jìn)位標(biāo)志位被清零,則忽略它。
假如調(diào)用成功,進(jìn)位標(biāo)志位被清零并且ECX包含在傳送緩沖區(qū)中的字節(jié)數(shù)。這個(gè)數(shù)值應(yīng)小于你要求的數(shù)值,所以你應(yīng)保持這個(gè)數(shù)值,V86MMGR_Free_Buffer待會(huì)要用到它。EDI的高字包含被分配的內(nèi)存塊的V86段地址,偏移地址在在低字中。進(jìn)位標(biāo)志位當(dāng)錯(cuò)誤發(fā)生時(shí)被置位。

V86MMGR_Free_Buffer和V86MMGR_Allocate_Buffer接受同樣的參數(shù)。

當(dāng)你調(diào)用V86MMGR_Allocate_Buffer時(shí),你在當(dāng)前VM的V86內(nèi)存范圍內(nèi)分配了一塊內(nèi)存,并且把其地址放到了EDI中。你可以使用這些服務(wù)傳送數(shù)據(jù)到V86中斷中或從V86中斷中取得數(shù)據(jù)。

在附加的API傳送中,V86內(nèi)存治理器也給其他VxDs提供了API映射服務(wù)。API映射服務(wù)是映射一些在擴(kuò)展內(nèi)存中的頁(yè)到每個(gè)VM的V86內(nèi)存范圍。你可以使用V86MMGR_Map_Pages執(zhí)行API映射。使用這個(gè)服務(wù),頁(yè)被映射到每個(gè)VM的同一線性地址空間上。如你僅僅工作在一個(gè)VM上,這將浪費(fèi)地址空間。因?yàn)锳PI映射比API傳送要慢,所以你盡可能使用API傳送方式。API映射僅僅使用在一些要訪問同一線性地址空間并作用到所有VM的V86操作上。

例子:

這個(gè)例子演示了API傳送方式,使用了int 21h的440Dh功能(從代碼66h)。這個(gè)中斷調(diào)用得到媒體ID,你的第一個(gè)固定磁盤的卷標(biāo)號(hào)。

;---------------------------------------------------------------
;                            VxDLabel.asm
;---------------------------------------------------------------
.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_IN99v_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
  VMMCall Get_Sys_VM_Handle
  mov Handle,ebx
  assume ebx:ptr cb_s
  mov ebp,[ebx+CB_Client_Pointer]
  mov ecx,sizeof MID
  stc
  push esi
  mov esi,OFFSET32 MediaID
  push ds
  pop fs
  VxDCall V86MMGR_Allocate_Buffer
  pop esi
  jc EndI
  mov AllocSize,ecx
  Push_Client_State
  VMMCall Begin_Nest_V86_Exec
  assume ebp:ptr Client_Byte_Reg_StrUC
  mov [ebp].Client_ch,8
  mov [ebp].Client_cl,66h
  assume ebp:ptr Client_Word_reg_struc
  mov edx,edi
  mov [ebp].Client_bx,3 ; drive A
  mov [ebp].Client_ax,440dh
  mov [ebp].Client_dx,dx
  shr edx,16
  mov [ebp].Client_ds,dx
  mov eax,21h
  VMMCall Exec_Int
  VMMCall End_Nest_Exec
  Pop_Client_State
  ;-------------------------------
  ; retrieve the data
  ;-------------------------------
  mov ecx,AllocSize
  stc
  mov ebx,Handle
  push esi
  mov esi,OFFSET32 MediaID
  push ds
  pop fs
  VxDCall V86MMGR_Free_Buffer
  pop esi
  mov edx,esi
  assume edx:ptr DIOCParams
  mov edi,[edx].lpvOutBuffer
  mov esi,OFFSET32 MediaID.midVolLabel
  mov ecx,11
  rep movsb
  mov byte ptr [edi],0

  mov ecx,[edx].lpcbBytesReturned
  mov dword ptr [edx],11
EndI:
.endif
xor eax,eax
ret
EndProc OnDeviceIoControl
VXD_PAGEABLE_CODE_ENDS

VXD_PAGEABLE_DATA_SEG
MID struct
  midInfoLevel dw 0
  midSerialNum dd ?
  midVolLabel db 11 dup(?)
  midFileSysType db 8 dup(?)
MID ends
MediaID MID <>
Handle dd ?
AllocSize dd ?
VXD_PAGEABLE_DATA_ENDS

end

;------------------------------------------------------------
;                        Label.asm
; The win32 VxD loader.
;------------------------------------------------------------
.386
.model flat,stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 讷河市| 行唐县| 沙湾县| 赤城县| 多伦县| 武清区| 东台市| 衡水市| 曲周县| 资阳市| 大英县| 确山县| 南涧| 千阳县| 长春市| 元氏县| 荣昌县| 商丘市| 仙桃市| 鄂州市| 新乐市| 东安县| 孟州市| 西林县| 长丰县| 霍林郭勒市| 绥宁县| 黑山县| 吉安市| 武城县| 彭水| 曲水县| 长子县| 新晃| 顺昌县| 龙山县| 陆丰市| 南宁市| 黄冈市| 蒲城县| 宁波市|