实验3虚拟存储器.docx

上传人:b****4 文档编号:3553162 上传时间:2022-11-23 格式:DOCX 页数:26 大小:36.14KB
下载 相关 举报
实验3虚拟存储器.docx_第1页
第1页 / 共26页
实验3虚拟存储器.docx_第2页
第2页 / 共26页
实验3虚拟存储器.docx_第3页
第3页 / 共26页
实验3虚拟存储器.docx_第4页
第4页 / 共26页
实验3虚拟存储器.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

实验3虚拟存储器.docx

《实验3虚拟存储器.docx》由会员分享,可在线阅读,更多相关《实验3虚拟存储器.docx(26页珍藏版)》请在冰豆网上搜索。

实验3虚拟存储器.docx

实验3虚拟存储器

实验3、Windows虚拟内存

(一)、虚拟内存

1背景知识

在Windows环境下,32位Windows系统中,232=4GB的虚拟地址空间被划分成两个部分:

低端2GB提供给进程使用,高端2GB提供给系统使用。

这意味着用户的应用程序代码,包括DLL以及进程使用的各种数据等,都装在用户进程地址空间内(低端2GB)。

用户过程的虚拟地址空间也被分成三部分:

1)虚拟内存的已调配区(committed):

具有备用的物理内存,根据该区域设定的访问权限,用户可以进行写、读或在其中执行程序等操作。

2)虚拟内存的保留区(reserved):

没有备用的物理内存,但有一定的访问权限o

3)虚拟内存的自由区(free):

不限定其用途,有相应的PAGE_NOACCESS权限。

与虚拟内存区相关的访问权限告知系统进程可在内存中进行何种类型的操作。

例如,用户不能在只有PAGE_READONLY权限的区域上进行写操作或执行程序;也不能在只有PAGE_EXECUTE权限的区域里进行读、写操作。

而具有PAGE_NOACCESS权限的特殊区域,则意味着不允许进程对其地址进行任何操作。

在进程装入之前,整个虚拟内存的地址空间都被设置为只有PAGE_NOACCESS权限的自由区域。

当系统装入进程代码和数据后,才将内存地址的空间标记为已调配区或保留区,并将诸如EXECUTE、READWRITE和READONLY的权限与这些区域相关联。

如表1所示,给出了MEMORY_BASIC_INFORMATION的结构,此数据描述了进程虚拟内存空间中一组虚拟内存页面的当前状态,其中State项表明这些区域是否为自由区、已调配区或保留区;Protect项则包含了Windows系统为这些区域添加了何种访问保护;Type项则表明这些区域是可执行图像、内存映射文件还是简单的私有内存。

VirtualQueryEX()API能让用户在指定的进程中,对虚拟内存地址的大小和属性进行检测。

Windows还提供了一整套能使用户精确控制应用程序的虚拟地址空间的虚拟内存API。

一些用于虚拟内存操作及检测的API如表2所示。

表1MEMORY_BASIC_INFORMATION结构的成员

成员名称

目的

PVOIDBaseAddress

虚拟内存区域开始处的指针

PVOIDAllocationBase

如果这个特定的区域为子分配区的话,则为虚拟内存外面区域的指针;否则,此值与BaseAddress相同

DWORDAllocationProtect

虚拟内存最初分配区域的保护属性。

其可能值包括:

PAGE_NOACCESS,PAGE_READONLY,PAGE_READWRITE和PAGE_EXECUTE_READ

DWORDRegionSize

虚拟内存区域的字节数

DWORDState

区域的当前分配状态。

其可能值为MEM_COMMIT,MEM_FREE和MEM_RESERVE

DW()RDProtect

虚拟内存当前区域的保护属性。

可能值与AllocationProtect成员的相同

DWORDType

虚拟内存区域中出现的页面类型。

可能值为MEM_IMAGE,MEM_MAPPED和MEM_PRIVATE

表2虚拟内存的API

APl名称

描述

VirtualQueryEx()

通过填充MEMORY_BASIC_INFORMATION结构检测进程内虚拟内存的区域

VirtuaAlloc()

保留或调配进程的部分虚拟内存,设置分配和保护标志

VirtualFree()

释放或收回应用程序使用的部分虚拟地址

VirtualProtect()

改变虚拟内存区域保护规范

VirtualLock()

防止系统将虚拟内存区域通过系统交换到页面文件中

VirtualUnlock()

释放虚拟内存的锁定区域,必要时,允许系统将其交换到页面文件中

提供虚拟内存分配功能的是VinualAlloc()API。

该API支持用户向系统要求新的虚拟内存或改变已分配内存的当前状态。

用户若想通过VirtualAlloc()函数使用虚拟内存,可以采用两种方式通知系统:

1)简单地将内存内容保存在地址空间内。

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

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

与VirtualAlloc()函数对应的是VirtualFree()函数,其作用是释放虚拟内存中的已调配页或保留页。

用户可利用dwFreeType参数将已调配页修改成保留页属性。

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

2实验目的

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

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

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

3实验内容与步骤

虚拟内存的检测

清单2所示的程序使用VirtualQueryEX()函数来检查虚拟内存空间。

步骤1:

在“开始”菜单中单击“程序”、“MicrosoftVisualStudio6.0”、

“MicrosoftVisualC++6.0”,进入VisualC++窗口。

步骤2:

运行以下程序清单

清单2检测进程的虚拟地址空间

#include

#include

#include

#include

#pragmacomment(lib,"shlwapi.lib")

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

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

inlineboolTestSet(DWORDdwTarget,DWORDdwMask)

{

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

}

#defineSHOWMASK(dwTarget,type)\

if(TestSet(dwTarget,PAGE_##type))\

{std:

:

cout<<","<<#type;}

voidShowProtection(DWORDdwTarget)

{

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);

}

//遍历整个虚拟内存并对用户显示其属性的工作程序的方法

voidWalkVM(HANDLEhProcess)

{

//首先,获得系统信息

SYSTEM_INFOsi;

:

:

ZeroMemory(&si,sizeof(si));

:

:

GetSystemInfo(&si);

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

MEMORY_BASIC_INFORMATIONmbi;

:

:

ZeroMemory(&mbi,sizeof(mbi));

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

LPCVOIDpBlock=(LPVOID)si.lpMinimumApplicationAddress;

while(pBlock

{

//获得下一个虚拟内存块的信息

if(:

:

VirtualQueryEx(

hProcess,//相关的进程

pBlock,//开始位置

&mbi,//缓冲区

sizeof(mbi))==sizeof(mbi))//大小的确认

{

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

LPCVOIDpEnd=(PBYTE)pBlock+mbi.RegionSize;

TCHARszSize[MAX_PATH];

:

:

StrFormatByteSize(mbi.RegionSize,szSize,MAX_PATH);

//显示块地址和大小

std:

:

cout.fill('0');

std:

:

cout<

:

hex<

:

setw(8)<<(DWORD)pBlock<<"-"

<

:

hex<

:

setw(8)<<(DWORD)pEnd

<<(strlen(szSize)==7?

"(":

"(")<

//显示块的状态

switch(mbi.State)

{

caseMEM_COMMIT:

std:

:

cout<<",Committed";

break;

caseMEM_FREE:

std:

:

cout<<",Free";

break;

caseMEM_RESERVE:

std:

:

cout<<",Reserved";

break;

}

//显示保护

if(mbi.Protect==0&&mbi.State!

=MEM_FREE)

{

mbi.Protect=PAGE_READONLY;

}

ShowProtection(mbi.Protect);

//显示类型

switch(mbi.Type)

{

caseMEM_IMAGE:

std:

:

cout<<",Image";

break;

caseMEM_MAPPED:

std:

:

cout<<",Mapped";

break;

caseMEM_PRIVATE:

std:

:

cout<<",Private";

break;

}

//检验可执行的影像

TCHARszFilename[MAX_PATH];

if(:

:

GetModuleFileName(

(HMODULE)pBlock,

szFilename,

MAX_PATH)>0)

{

//除去路径并显示

:

:

PathStripPath(szFilename);

std:

:

cout<<",Module:

"<

}

std:

:

cout<

:

endl;

//移动块指针以获得下一个块

pBlock=pEnd;

}

}

}

voidmain()

{

//遍历当前进程的虚拟内存

:

:

WalkVM(:

:

GetCurrentProcess());

}

清单2中显示一个WalkVM()函数开始于某个进程可访问的最低端虚拟地址处,并在其中显示各块虚拟内存的特性。

虚拟内存中的块由VirtualQueryEx()APl定义成连续块或具有相同状态(自由区、已调配区等)的内存,并分配以一组统一的保护标志(只读、可执行等)。

回答下列问题:

1)分析运行结果

committed、reserved、free分别表示什么含义?

答:

虚拟内存的已调配区、虚拟内存的保留区、虚拟内存的自由区

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

00010000—00012000<8.00KB>Committed,READWRITE,Private可描述为:

具有READWRITE权限的已调配私有内存区。

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

(表格可以自己画,通过把运行结果复制到word中文字转换成表格)

表1实验记录

地址

大小

虚拟地址

空间类型

访问权限

描述(type)

 00012000-00020000

 56.0KB

free

 NOACCESS

 

 00021000-00030000

60.0KB 

free

 NOACCESS

 

 00133000-00140000

 52.0KB

free

 NOACCESS

 

 00276000-00280000

40.0KB

free

 NOACCESS

 

 002C1000-002D0000

 60.0KB

free

NOACCESS

 

00311000-00320000

60.0KB

free

NOACCESS

 

00326000-00330000

40.0KB

free

NOACCESS

 

00371000-00380000

60.0KB

free

NOACCESS

 

00391000-003A0000

60.0KB

free

NOACCESS

 

0031A000-003B0000

60.0KB

free

NOACCESS

 

003C3000-003D0000

52.0KB

free

NOACCESS

 

003E0000-00400000

128KB

free

NOACCESS

 

 00485000-00490000

44.0KB

free

NOACCESS

 

00558000=00560000

32.0KB

free

NOACCESS

 

00663000-00670000

52.0KB

free

NOACCCESS

 

00970000-62C20000

1.53GB

free

NOACCESS

 

62C29000-73FA0000

275MB

free

NOACCESS

 

1400B000-76300000

34.9MB

free

NOACCESS

 

7631D000-77BE0000

24.7MB

free

 NOACCESS

 

 77C38000-77D10000

864KB

free

NOACCESS

 

77E49000-77E51000

28.0KB

free

NOACCESS

 

77EE3000-77EF0000

52.0KB

free

NOACCESS

 

77F39000-77F40000

28.0KB

free

NOACCESS

 

77EE3000-77EF0000

52.0KB

free

NOACCESS

 

77F39000-77F40000

28.0KB

free

NOACCESS

 

将系统当前的已调配区(committed)虚拟地址空间填入表2中。

 

表2实验记录

地址

大小

虚拟地址

空间类型

访问权限

描述(type)

 00010000-00012000

 8.00KB

committed

 READWRITE

 Private

 00020000-00021000

 4.00KB

committed

 READWRITE

 Private

 0012c000-0012d000

 4.00KB

committed

 GUARD,READWRITE

 Private

 0012d000-00130000

 12.0KB

committed

 READWRITE

 Private

 00130000-00133000

 12.0KB

committed

 READONLY

 Mapped

 00140000-00145000

 20.0KB

committed

 READWRITE

 Private

 00240000-00246000

 24.0KB

committed

 READWRITE

 Private

 00250000-00253000

 12.0KB

committed

 READWRITE

 Mapped

 00260000-00276000

 88.0KB

committed

 READONLY

 Mapped

 00280000-002c1000

 260KB

committed

 READONLY

 Mapped

 002d0000-00311000

 260KB

committed

 READONLY

 Mapped

 00320000-00326000

 24.0KB

committed

 READONLY

 Mapped

 00330000-00371000

 260KB

committed

 READONLY

 Mapped

 00380000-00388000

 32.0KB

committed

 READWRITE

 Private

 00390000-00391000

 4.00KB

committed

 READWRITE

 Private

 003a0000-003a1000

 4.00KB

committed

 READWRITE

 Private

 003b0000-003b4000

 16.0KB

committed

 READWRITE

 Private

 003c0000-003c3000

 12.0KB

committed

 READONLY

 Mapped

 003d0000-003d3000

 12.0KB

committed

 READWRITE

 Private

 00400000-00401000

 4.00KB

committed

READONLY

 Image,Module:

03.exe

 00401000-00470000

 444KB

committed

 EXECUTE_READ

 Image

 00470000-00478000

 32.0KB

committed

 READONLY

 Image

 00478000-0047b000

 12.0KB

committed

 READWRITE

 Image

 0047b000-0047d000

 8.00KB

committed

 WRITECOPY

 Image

 0047d000-00481000

 16.0KB

committed

 READWRITE

 Image

 

将系统当前的保留区(reserved)虚拟地址空间填入表3中。

 

表3实验记录

地址

大小

虚拟地址

空间类型

访问权限

描述(type)

 00030000-0012c000

 0.98MB

reserved

 READONLY

 Private

 00145000-00240000

 0.98MB

reserved

READONLY

 Private

 00246000-00250000

 40.KB

reserved

READONLY

Private

 00253000-00260000

 52.0KB

reserved

 READONLY

 Mapped

 00388000-00390000

 32.0KB

reserved

 READONLY

Private

 003b4000-003c0000

 48.0KB

reserved

 READONLY

 Private

 003d3000-003e0000

 52.0KB

reserved

 READONLY

 Private

 00495000-00550000

 748KB

reserved

 READONLY

 Mapped

 00552000-00558000

 24.0KB

reserved

 READONLY

 Mapped

 006d5000-00970000

 2.60MB

reserved

 READONLY

 Mapped

2)从上述输出结果,对照分析程序,请简单描述程序运行的流程:

答:

该程序,从主函数出发,调用voidWalkVM(HANDLEhProcess)函数,voidWalkVM(HANDLEhProcess)函数先得系统信息,再分配应用程序地址空间,接下来就是做循环函数内做循环:

首先每次获得下一个虚拟程序内存的信息——计算块的结尾及其大小,然后再显示块的大小与位置,及其状态,显示保护方式显示类型,检查可执行的影像—除去文件名的路径并将文件名显示出来——移动块指针以获得下一个块,从新做循环。

3)实验总结

(根据实验结果及自己查阅相关资料写出VirtualAlloc()函数的作用,各个参数的可能值及含义。

列出对虚拟内存的认识)

答:

通过本次实验,体会学习检查虚拟内存空间或对其进行操作,windows2000的内存采用,进而了解进程和windows为使用内存而提供的一些扩展功能。

虚拟内存是计算机系统内存管理的一种技术。

它使得应用成粗认为它拥有连续的可用的内存,而实际上,它通常是被隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

virtualalloc是可以自己控制页面的保留,提交,释放的实际的。

实际上我们申请的内存没有使用的时候,都是被放在内存页面中,在使用的时候才会被切换到真正的物理存储器里。

可能的数值

含义

MEM_COMMIT为0x1000

分配指定保留的内存页的物理存储在内存或磁盘上的分页文件。

该函数的内存初始化为零。

保留并承诺在一个步骤的页面,调用VirtualAlloc的MEM_COMMIT|MEM_RESERVE。

该函数将失败,如果你尝试提交一个还没有被保留页。

由此产生的错误代码是ERROR_INVALID_ADDRESS。

尝试提交一个已经提交的页面不会导致函数失败。

这意味着你可以承诺不首先确定当前承诺在每一页的状态页面。

MEM_RESERVE0x2000

保留在没有任何实际的物理存储在内存或磁盘上的分页文件分配一个进程的虚拟地址空间的范围。

你可以提交保留页的后续调用VirtualAlloc的功能。

保留并承诺在一个步骤的页面,调用VirtualAlloc的MEM_COMMIT|MEM_RESERVE。

内存分配的功能,如其他的malloc和Lo

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1