计算机操作系统实验指导书 联系客服

发布时间 : 星期五 文章计算机操作系统实验指导书更新完毕开始阅读8f9190d380eb6294dd886c81

《操作系统管理》实验指导书

VirsualUnlock() 释放虚拟内存的锁定区域,必要时,允许系统将其交换到页面文件中 提供虚拟内存分配功能的是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. 虚拟内存的检测

清单5-2所示的程序使用VirtualQueryEX()函数来检查虚拟内存空间。 步骤1:登录进入Windows 2000 Professional。

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

步骤3:在工具栏单击“打开”按钮,在“打开”对话框中找到并打开实验源程序5-2.cpp。 清单5-2 检测进程的虚拟地址空间 // 工程vmwalker #include #include #include #include

#pragma comment(lib, \

// 以可读方式对用户显示保护的辅助方法。

// 保护标记表示允许应用程序对内存进行访问的类型 // 以及操作系统强制访问的类型

inline bool TestSet(DWORD dwTarget, DWORD dwMask)

34

《操作系统管理》实验指导书

{

return ((dwTarget &dwMask) == dwMask) ; }

# define SHOWMASK(dwTarget, type) \\ if (TestSet(dwTarget, PAGE_##type) ) \\ {std :: cout << \

void ShowProtection(DWORD dwTarget) {

SHOWMASK(dwTarget, READONLY) ; SHOWMASK(dwTarget, GUARD) ; SHOWMASK(dwTarget, NOCACHE) ; SHOWMASK(dwTarget, READWRITE) ; SHOWMASK(dwTarget, WRITECOPY) ; SHOWMASK(dwTarget, EXECUTE) ;

SHOWMASK(dwTarget, EXECUTE_READ) ;

SHOWMASK(dwTarget, EXECUTE_READWRITE) ; SHOWMASK(dwTarget, EXECUTE_WRITECOPY) ; SHOWMASK(dwTarget, NOACCESS) ; }

// 遍历整个虚拟内存并对用户显示其属性的工作程序的方法 void WalkVM(HANDLE hProcess) {

// 首先,获得系统信息 SYSTEM_INFO si;

:: ZeroMemory(&si, sizeof(si) ) ; :: GetSystemInfo(&si) ;

// 分配要存放信息的缓冲区

MEMORY_BASIC_INFORMATION mbi; :: ZeroMemory(&mbi, sizeof(mbi) ) ;

// 循环整个应用程序地址空间

LPCVOID pBlock = (LPVOID) si.lpMinimumApplicationAddress; while (pBlock < si.lpMaximumApplicationAddress) {

// 获得下一个虚拟内存块的信息 if (:: VirtualQueryEx( hProcess, // 相关的进程 pBlock, // 开始位置 &mbi, // 缓冲区 sizeof(mbi))==sizeof(mbi) ) // 大小的确认 {

// 计算块的结尾及其大小

LPCVOID pEnd = (PBYTE) pBlock + mbi.RegionSize; TCHAR szSize[MAX_PATH];

:: StrFormatByteSize(mbi.RegionSize, szSize, MAX_PATH) ;

// 显示块地址和大小 std :: cout.fill ('0') ; std :: cout

<< std :: hex << std :: setw(8) << (DWORD) pBlock << \

<< std :: hex << std :: setw(8) << (DWORD) pEnd << (:: strlen(szSize)==7? \ << \

35

《操作系统管理》实验指导书

// 显示块的状态 switch(mbi.State) {

case MEM_COMMIT : std :: cout << \ break;

case MEM_FREE : std :: cout << \ break;

case MEM_RESERVE :

} } }

void main() {

std :: cout << \ break; } // 显示保护 if(mbi.Protect==0 && mbi.State!=MEM_FREE) {

mbi.Protect=PAGE_READONLY; } ShowProtection(mbi.Protect); // 显示类型

switch(mbi.Type){

case MEM_IMAGE : std :: cout << \ break; case MEM_MAPPED: std :: cout << \ break;

case MEM_PRIVATE : std :: cout << \ break; } // 检验可执行的影像

TCHAR szFilename [MAX_PATH] ; if (:: GetModuleFileName ( (HMODULE) pBlock, // 实际虚拟内存的模块句柄 szFilename, //完全指定的文件名称 MAX_PATH)>0) //实际使用的缓冲区大小 {

// 除去路径并显示

:: PathStripPath(szFilename) ;

std :: cout << \} std :: cout << std :: endl; // 移动块指针以获得下一下个块 pBlock = pEnd; 36

《操作系统管理》实验指导书

// 遍历当前进程的虚拟内存 ::WalkVM(::GetCurrentProcess()); }

清单5-2中显示一个walkVM()函数开始于某个进程可访问的最低端虚拟地址处,并在其中显示各块虚拟内存的特性。虚拟内存中的块由VirsualQueryEX()API定义成连续快或具有相同状态(自由区,已调配区等)的内存,并分配以一组统一的保护标志(只读、可执行等)。

步骤4:单击“Build”菜单中的“Compile 5-2.cpp”命令,并单击“是”按钮确认。系统对5-2.cpp进行编译。

步骤5:编译完成后,单击“Build”菜单中的“Build 5-2.exe”命令,建立5-2.exe可执行文件。

操作能否正常进行?如果不行,则可能的原因是什么?

____________________________________________________________________ ________________________________________________________________________ 步骤6:在工具栏单击“Execute Program” (执行程序) 按钮,执行5-2.exe程序。 1)分析运行结果(如果运行不成功,则可能的原因是什么)

按committed,reserved,free等三种虚拟地址空间分别记录实验数据,其中“描述”是对该组数据的简单描述,例如,对下列一组数据:

00010000-00012000<8.00KB>Committed,READWRITE,Private可描述为:具有READWRITE权限的已调配私有内存区。

将系统当前的自由区(Free)虚拟地址空间填入表3-3中。

表3-3 实验记录 地址 大小 虚拟空间类型 free free free free free free free 表3-4 实验记录 地址 大小 虚拟空间类型 Committed Committed Committed Committed Committed Committed Committed 访问权限 描述 访问权限 描述 将系统当前的已调配区(Committed)虚拟地址空间填入表3-4中。 将系统当前的保留区(Reserved)虚拟地址空间填入表3-5中。 表3-5 实验记录 地址 大小 虚拟空间类型 Reserved Reserved Reserved 访问权限 描述 37