虚拟8086模式的内存管理

原创 2001年06月18日 23:40:00

虚拟8086模式的内存管理


下边我们用到的V86即指虚拟8086模式。 在以前的教程中,你学习了怎样模拟V86中断,但还有一个问题没有解决:在VxD和V86代码之间交换数据。我们将在此学习如何使用V86内存管理器来实现这个功能。在这里下载例子程序

理论

假如你的VxD和一些V86程序一起运行,如何传送大量数据到V86程序中或从V86程序中传送大量数据迟早是一个大问题。通过寄存器传送大量数据是不现实的。可能你的下一个想法是在ring0中分配一大块内存,并且通过一些寄存器传送其指针到V86程序,使其能访问这些数据。假如你这样做,可能会破坏你的系统,因为V86的地址定位方式需要segment:offset对,而不是线性定位方式。对这个问题,有很多解决的方法。然而,我选择了一个由V86内存管理器提供的一种简便的方法。

如你能在你可使用的V86内存范围内找到一个空闲的内存块作为通讯缓冲区,这将解决其中的一个问题。然而,指针传送的问题依然存在。你可以通过V86内存管理器的服务来解决这两个问题。V86内存管理器是为V86应用管理内存的静态VxD。它还为V86应用提供EMS和XMS服务和为其他VxD提供API传送服务。API传送是一个从ring0拷贝数据到V86范围内的缓冲区并且传送V86缓冲区地址到V86代码的过程。V86内存管理器有一个在V86内存范围内的传送缓冲区,其含有VxD拷贝到V86内存范围内的数据,反之亦然。初始的缓冲区是4K。你以调用V86MMGR_Set_Mapping_Info来增加它的大小。

现在你知道了传送缓冲区,我们如何拷入或拷出数据呢?这个问题通过调用两个服务来解决:V86MMGR_Allocate_Buffer和V86MMGR_Free_Buffer。

V86MMGR_Allocate_Buffer从传送缓冲区分配一块内存并且从ring0拷贝一些数据到分配的V86缓冲区。V86MMGR_Free_Buffer正好相反:它从分配的V86内存块拷贝一些数据到ring0缓冲区并且释放由V86MMGR_Allocate_Buffer分配的内存块。

记住,V86在内存管理器象堆栈一样管理被分配的缓冲区。这意味着分配/释放必须按先进后出的规则。所以如你调用了两次V86MMGR_Allocate_Buffer,第一个V86MMGR_Free_Buffer将释放由第二个V86MMGR_Allocate_Buffer调用而分配的缓冲区。

我们来看一下V86MMGR_Allocate_Buffer的定义,它是一个基本寄存器传送参数的服务。

  • EBX 当前VM的句柄
  • EBP 指向当前VM的客户寄存器结构的指针
  • ECX 从传送缓冲区分配的字节数 CARRY FLAG 进位标志位,如你不想从ring0缓冲区拷贝数据到分配的内存块就清零, 如你想从ring0缓冲区拷贝数据到分配的内存块就置1
  • FS:ESI 指向ring0缓冲区的selector:offset指针,缓冲区中有要被拷贝到被分配的 缓冲区中的数据如果进位标志位被清零,则忽略它。

假如调用成功,进位标志位被清零并且ECX包含在传送缓冲区中的字节数。这个数值应小于你要求的数值,所以你应保持这个数值,V86MMGR_Free_Buffer待会要用到它。EDI的高字包含被分配的内存块的V86段地址,偏移地址在在低字中。进位标志位当错误发生时被置位。

V86MMGR_Free_Buffer和V86MMGR_Allocate_Buffer接受同样的参数。

当你调用V86MMGR_Allocate_Buffer时,你在当前VM的V86内存范围内分配了一块内存,并且把其地址放到了EDI中。你可以使用这些服务传送数据到V86中断中或从V86中断中取得数据。

在附加的API传送中,V86内存管理器也给其他VxDs提供了API映射服务。API映射服务是映射一些在扩展内存中的页到每个VM的V86内存范围。你可以使用V86MMGR_Map_Pages执行API映射。使用这个服务,页被映射到每个VM的同一线性地址空间上。如你仅仅工作在一个VM上,这将浪费地址空间。因为API映射比API传送要慢,所以你尽可能使用API传送方式。API映射仅仅使用在一些要访问同一线性地址空间并作用到所有VM的V86操作上。

例子:

这个例子演示了API传送方式,使用了int 21h的440Dh功能(从代码66h)。这个中断调用得到媒体ID,你的第一个固定磁盘的卷标号。


讲解

我们首先分析lable.asm,它是一个加载了VxD的WIN32应用程序。

invoke DeviceIoControl,hVxD,1,NULL,0,addr DiskLabel,12,addr BytesReturned,NULL

它调用DeviceIoControl,设备代码是1,没有输入缓冲区,一个指向输出缓冲区的指针及其大小。DiskLable是一个接收由VxD返回的卷标号的缓冲区。BytesReturned变量存有返回的字节数。这个例子说明了怎样传送数据和从VxD接收数据:你传送输入/输出缓冲区给VxD并且VxD读取/写入数据到指定的缓冲区。

我们下面看看VxD代码。


当一个VxD接收W32_DeviceIoControl消息,它调用Get_Sys_VM_Handle得到系统VM的句柄并把它存在一个叫Handle的变量中。下面将从VM控制块中提取指向客户寄存器结构的指针到EBP。


下面,准备传送到V86MMGR_Allocate_Buffer的参数。我们必须初始化被分配的缓冲区。我们把MediaID的偏移量送到ESI中,并且把选择子放在FS中,然后调用V86MMGR_Allocate_Buffer。你等会要恢复指向DIOCParams的指针,所以我们必须通过push esi 和pop esi来保护它。


我们在客户寄存器结构中准备参数值来执行int 21h的440Dh功能(从代码66h),得到盘C的媒体ID。我们拷贝edi的值到edx中(edi中有由V86MMGR_Allocate_Buffer分配的内存块的V86地址)。


调用了int 21h的440Dh功能(从代码66h)后,在ds:dx中得到一指向一个MID结构的指针,我们必须把在edx中的segment:offset对转换成两个部分并把它们放到合适的寄存器映象中。


当一切都准备好了,我们将运行Exec_Int去模拟一个中断。


当Exec_Int返回时,分配的缓冲已经由我们想要的信息填满了。下一步是检索信息。我们使用 V86MMGR_Free_Buffer来完成这个目标。这个服务释放由V86MMGR_Allocate_Memory分配的内存块,并且从分配的内存块中拷贝数据到ring0中的内存块。象V86MMGR_Allocate_Memory,如果你想要进行拷贝操作,你必须先把进位标志位置1,再调用服务。


我们在ring0中得到这个信息后,拷贝这个卷标值到Win32应用程序提供的缓冲区中。我们可以用DIOCParams的成员lpvOutBuffer来访问它。

虚拟8086模式

十一.虚拟8086模式 继推出80386之后,Intel又推出了80386、Pentium和Pentium PRO。这些处理器都具有 实模式和保护模式两种工作方式。前面已介绍过,实模式与8086...
  • SpadgerZ
  • SpadgerZ
  • 2016年11月08日 20:06
  • 1007

8086的最小模式和最大模式

一、最小模式和最大模式 8086/8088可以在两种工作模式下工作,即最小模式和最大模式。 最小模式--即系统中只有8086(或8088)一个微处理器。最小模式是单处理器系统。系统中所需要的控制信...
  • BeautifulEncounter
  • BeautifulEncounter
  • 2012年09月18日 12:40
  • 4300

实模式、保护模式、虚拟8086模式

1、386处理器的三种工作模式   一般来说,80x86(80386及其以后的各代CPU)可以在三种模式下运转:实模式,保护模式,虚拟8086模式。实模式就是古老的MS-DOS的运行环境。Win95...
  • macrossdzh
  • macrossdzh
  • 2012年04月27日 22:32
  • 941

实模式 保护模式 虚拟8086模式

 一直以来,都搞不清楚这几个概念。在网上搜了一下,把它晒上,不会再忘记! 有其它的内容,请看到的朋友请补充。      从80386开始,cpu有三种工作方式:实模式,保护模式和虚拟8086模式。只有...
  • jimo1986
  • jimo1986
  • 2010年08月22日 22:02
  • 64

8086最小模式原理总结

一、8086芯片引脚定义 引脚功能简单描述: 因为本篇文章的目的是理解8086系统的原理,所以只讨论与程序设计相关的功能,其他方面只是简单略过。 AD0-AD15 : 地址/数据复用线 ...
  • codesnail
  • codesnail
  • 2011年11月28日 16:49
  • 6566

windows虚拟内存管理

内存管理是操作系统非常重要的部分,处理器每一次的升级都会给内存管理方式带来巨大的变化,向早期的8086cpu的分段式管理,到后来的80x86 系列的32位cpu推出的保护模式和段页式管理。在应用程序中...
  • lanuage
  • lanuage
  • 2016年07月21日 09:22
  • 2061

计算机原理学习(5)-- x86-16 CPU和内存管理

前言 前面我们已经了解了计算机硬件的工作原理,以及操作系统的发展。我们知道是内存把计算机硬件和软件联系了起来。不夸张的说,了解了软件在内存中的结构,就基本了解了程序最底层的运行原理。所以从这一篇开始,...
  • cc_net
  • cc_net
  • 2013年10月24日 19:31
  • 14527

解释术语:虚拟内存、缺页中断、抖动

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存 (一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片, 还有部分暂时存储在外部磁盘存储器上,在需要时...
  • banbanlin
  • banbanlin
  • 2014年09月25日 17:04
  • 3763

操作系统——虚拟内存管理

os中有物理地址和虚拟地址(逻辑地址)的区别 物理地址就是实际的物理内存的地址,逻辑地址是程序指令使用的地址。页表的作用就是实现逻辑地址到物理地址的映射。 x86的32位地址,前20位用于查找页表 ...
  • yyf_it
  • yyf_it
  • 2016年07月28日 17:57
  • 314

8086实时时钟实验(一)——《x86汇编语言:从实模式到保护模式》05

1.代码清单 ;代码清单9-1 ;文件名:c09_1.asm ;文件说明:用户程序 ;创建日期:2011-4-16 ...
  • u013490896
  • u013490896
  • 2016年01月01日 23:21
  • 1456
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:虚拟8086模式的内存管理
举报原因:
原因补充:

(最多只允许输入30个字)