实验3虚拟存储器Word文档格式.docx
《实验3虚拟存储器Word文档格式.docx》由会员分享,可在线阅读,更多相关《实验3虚拟存储器Word文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
![实验3虚拟存储器Word文档格式.docx](https://file1.bdocx.com/fileroot1/2022-11/23/4942a03f-7f69-40a2-a833-27e9709223ea/4942a03f-7f69-40a2-a833-27e9709223ea1.gif)
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<
windows.h>
iostream>
shlwapi.h>
iomanip>
#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;
mbi,sizeof(mbi));
//循环整个应用程序地址空间
LPCVOIDpBlock=(LPVOID)si.lpMinimumApplicationAddress;
while(pBlock<
si.lpMaximumApplicationAddress)
{
//获得下一个虚拟内存块的信息
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:
hex<
setw(8)<
(DWORD)pBlock<
-"
<
(DWORD)pEnd
(strlen(szSize)==7?
("
)<
szSize<
)"
;
//显示块的状态
switch(mbi.State)
{
caseMEM_COMMIT:
std:
Committed"
break;
caseMEM_FREE:
Free"
caseMEM_RESERVE:
Reserved"
}
//显示保护
if(mbi.Protect==0&
&
mbi.State!
=MEM_FREE)
mbi.Protect=PAGE_READONLY;
ShowProtection(mbi.Protect);
//显示类型
switch(mbi.Type)
caseMEM_IMAGE:
std:
Image"
break;
caseMEM_MAPPED:
Mapped"
caseMEM_PRIVATE:
Private"
//检验可执行的影像
TCHARszFilename[MAX_PATH];
if(:
GetModuleFileName(
(HMODULE)pBlock,
szFilename,
MAX_PATH)>
0)
//除去路径并显示
:
PathStripPath(szFilename);
Module:
szFilename;
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
00133000-00140000
52.0KB
00276000-00280000
40.0KB
002C1000-002D0000
60.0KB
00311000-00320000
00326000-00330000
00371000-00380000
00391000-003A0000
0031A000-003B0000
003C3000-003D0000
003E0000-00400000
128KB
00485000-00490000
44.0KB
00558000=00560000
32.0KB
00663000-00670000
NOACCCESS
00970000-62C20000
1.53GB
62C29000-73FA0000
275MB
1400B000-76300000
34.9MB
7631D000-77BE0000
24.7MB
77C38000-77D10000
864KB
77E49000-77E51000
28.0KB
77EE3000-77EF0000
77F39000-77F40000
将系统当前的已调配区(committed)虚拟地址空间填入表2中。
表2实验记录
00010000-00012000
8.00KB
committed
READWRITE
Private
00020000-00021000
4.00KB
0012c000-0012d000
GUARD,READWRITE
0012d000-00130000
12.0KB
00130000-00133000
READONLY
Mapped
00140000-00145000
20.0KB
00240000-00246000
24.0KB
00250000-00253000
00260000-00276000
88.0KB
00280000-002c1000
260KB
002d0000-00311000
00320000-00326000
00330000-00371000
00380000-00388000
32.0KB
00390000-00391000
003a0000-003a1000
003b0000-003b4000
16.0KB
003c0000-003c3000
003d0000-003d3000
00400000-00401000
Image,Module:
03.exe
00401000-00470000
444KB
EXECUTE_READ
Image
00470000-00478000
00478000-0047b000
0047b000-0047d000
WRITECOPY
0047d000-00481000
将系统当前的保留区(reserved)虚拟地址空间填入表3中。
表3实验记录
00030000-0012c000
0.98MB
reserved
00145000-00240000
00246000-00250000
40.KB
00253000-00260000
00388000-00390000
003b4000-003c0000
48.0KB
003d3000-003e0000
00495000-00550000
748KB
00552000-00558000
24.0KB
006d5000-00970000
2.60MB
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