实验3-2windows2000,虚拟内存.doc

实验3 存储管理 3-2 Windows 2000虚拟内存 实验估计时间120分钟 背景知识 实验目的 工具/准备工作 实验内容与步骤 背景知识 在Windows 2000环境下,4GB的虚拟地址空间被划分成两个部分低端2GB提供给进程使用,高端2GB提供给系统使用。这意味着用户的应用程序代码,包括DLL以及进程使用的各种数据等,都装在用户进程地址空间内 低端2GB 。用户过程的虚拟地址空间也被分成三部分 1 虚拟内存的已调配区 committed 具有备用的物理内存,根据该区域设定的访问权限,用户可以进行写、读或在其中执行程序等操作。

2 虚拟内存的保留区 reserved 没有备用的物理内存,但有一定的访问权限。

3 虚拟内存的自由区 free 不限定其用途,有相应的PAGE_NOACCESS权限。

与虚拟内存区相关的访问权限告知系统进程可在内存中进行何种类型的操作。例如,用户不能在只有PAGE_READONLY权限的区域上进行写操作或执行程序;
也不能在只有PAGE_CUTE权限的区域里进行读、写操作。而具有PAGE_ NOACCESS权限的特殊区域,则意味着不允许进程对其地址进行任何操作。

在进程装入之前,整个虚拟内存的地址空间都被设置为只有PAGE_NOACCESS权限的自由区域。当系统装入进程代码和数据后,才将内存地址的空间标记为已调配区或保留区,并将诸如CUTE、READWRITE和READONLY的权限与这些区域相关联。

清单3-2还显示了如何理解Virtual QueryEX API填充的MEMORY_BASIC_ INATION结构,如表5-l所示。此数据描述了进程虚拟内存空间中一组虚拟内存页面的当前状态。其中State项表明这些区域是否为自由区、已调配区或保留区;
Protect项则包含了Windows系统为这些区域添加了何种访问保护;
Type项则表明这些区域是可执行图像、内存映射文件还是简单的私有内存。VirtualQueryEX API能让用户在指定的进程中,对虚拟内存地址的大小和属性进行检测。

Windows还提供了一整套能使用户精确控制应用程序的虚拟地址空间的虚拟内存API。一些用于虚拟内存操作及检测的API见表3-3所示。

表3-2 MEMORY_BASIC_INATION结构的成员 成员名称 目的 PVOID BaseAddress 虚拟内存区域开始处的指针 PVOID AllocationBase 如果这个特定的区域为子分配区的话,则为虚拟内存外面区域的指针;
否则此值与BaseAddress相同 DWORD AllocationProtect 虚拟内存最初分配区域的保护属性。其可能值包括 PAGE_NOACCESS,PAGE_READONLY,PAGE_READWRITE和PAGE _CUTE_READ DWORD RegionSize 虚拟内存区域的字节数 DWORD State 区域的当前分配状态。其可能值为MEM_COMMIT,MEM_FREE和MEM_RESERVE DWORD Protect 虚拟内存当前区域的保护属性。可能值与AllocationProtect成员的相同 DWORD Type 虚拟内存区域中出现的页面类型。可能值为MEM_IMAGE, MEM_MAPPED和MEM_PRIVATE 表3-3 虚拟内存的API API名称 描述 VirtualQueryEx 通过填充MEMORY_BASIC_INATION结构检测进程内虚拟内存的区域 VirtualAlloc 保留或调配进程的部分虚拟内存,设置分配和保护标志 VirtualFree 释放或收回应用程序使用的部分虚拟地址 VirtualProtect 改变虚拟内存区域保护规范 VirtualLock 防止系统将虚拟内存区域通过系统交换到页面文件中 VirtualUnlock 释放虚拟内存的锁定区域,必要时,允许系统将其交换到页面文件中 提供虚拟内存分配功能的是VirtualAlloc API。该API支持用户向系统要求新的虚拟内存或改变已分配内存的当前状态。用户若想通过VirtualAlloc 函数使用虚拟内存,可以采用两种方式通知系统 1 简单地将内存内容保存在地址空间内;

2 请求系统返回带有物理存储区 RAM的空间或换页文件 的部分地址空间。

用户可以用flAllocation Type参数 commit和reserve 来定义这些方式,用户可以通知Windows按只读、读写、不可读写、执行或特殊方式来处理新的虚拟内存。

与VirtualAlloc 函数对应的是VirtualFree 函数,其作用是释放虚拟内存中的已调配页或保留页。用户可利用dwFree Type参数将已调配页修改成保留页属性。

VirtualProtect 是VirtualAlloc 的一个辅助函数,利用它可以改变虚拟内存区的保护规范。

实验目的 1 通过实验了解Windows 2000内存的使用,学习如何在应用程序中管理内存,体会Windows应用程序内存的简单性和自我防护能力。

2 学习检查虚拟内存空间或对其进行操作;

3 了解Windows 2000的内存结构和虚拟内存的管理,进而了解进程堆和Windows为使用内存而提供的一些扩展功能。

工具/准备工作 在开始本实验之前,请回顾教科书的相关内容。

您需要做以下准备 1 一台运行Windows 2000 Professional操作系统的计算机。

2 计算机中需安装Visual C 6.0专业版或企业版。

实验内容与步骤 1. 虚拟内存的检测 2. 虚拟内存操作 1. 虚拟内存的检测 清单3-2所示程序使用VirtualQueryEX 函数来检查虚拟内存空间。

步骤1登录进入Windows 2000 Professional。

步骤2在“开始”菜单中单击“程序-Microsoft Visual Studio 6.0 – Microsoft Visual C 6.0”命令,进入Visual C窗口。

步骤3在工具栏单击“打开”按钮,在“打开”对话框中找到并打开实验源程序3-2.cpp。

清单3-2 检测进程的虚拟地址空间 // 工程vmwalker include include include include pragma commentlib, “Shlwapi.lib“ // 以可读方式对用户显示保护的辅助方法。

// 保护标记表示允许应用程序对内存进行访问的类型 // 以及操作系统强制访问的类型 inline bool TestSetDWORD dwTarget, DWORD dwMask { return dwTarget } define SHOWMASKdwTarget, type \ if TestSetdwTarget, PAGE_type \ {std cout “, “ type; } void ShowProtectionDWORD dwTarget { SHOWMASKdwTarget, READONLY ; SHOWMASKdwTarget, GUARD ; SHOWMASKdwTarget, NOCACHE ; SHOWMASKdwTarget, READWRITE ; SHOWMASKdwTarget, WRITECOPY ; SHOWMASKdwTarget, CUTE ; SHOWMASKdwTarget, CUTE_READ ; SHOWMASKdwTarget, CUTE_READWRITE ; SHOWMASKdwTarget, CUTE_WRITECOPY ; SHOWMASKdwTarget, NOACCESS ; } // 遍历整个虚拟内存并对用户显示其属性的工作程序的方法 void WalkVMHANDLE hProcess { // 首先,获得系统信息 SYSTEM_INFO si; ZeroMemory GetSystemInfo // 分配要存放信息的缓冲区 MEMORY_BASIC_INATION mbi; ZeroMemory // 循环整个应用程序地址空间 LPCVOID pBlock LPVOID si.lpMinimumApplicationAddress; while pBlock si.lpMaximumApplicationAddress { // 获得下一个虚拟内存块的信息 if VirtualQueryEx hProcess,// 相关的进程 pBlock, // 开始位置 TCHAR szSize[MAX_PATH]; StratByteSizembi.RegionSize, szSize, MAX_PATH ; // 显示块地址和大小 std cout.fill 0 ; std cout std hex std setw8 DWORD pBlock “-“ std hex std setw8 DWORD pEnd strlenszSize7 “ “ “ “ szSize “ “ ; // 显示块的状态 switchmbi.State { case MEM_COMMIT std c