型变量的指针指向这个空间
If(p=VirtualAlloc(0,sizeof(int),MEM_RESERVE|MEM_COMMIT)){
printf(“Allocated %d bytes virtual memory of 0x%x\\n\\n”,sizeof(int),d);
//输出原始整型变量的值
printf(\ //修改整型变量的值为0xFFFFFFFF *p=0xFFFFFFFF;
//输出修改后的整型变量的值
printf(\ printf(\ // 调用API函数Sleep,等待10秒钟 Sleep(10000);
// 调用API函数VirtualFree,释放之前分配的整型变量的空间 if(VirtualFree(p,0,MEM_RELEASE))
printf(\ else{
//若释放不成功,打印输出错误,并返回-1。 printf(\ return -1;
}
return 0; }
22)代码修改完毕后,生成EOS应用程序项目,启动调试,输出结果如图所示。
在应用程序分配虚拟页后,利用10秒后才释放虚拟页的间隙,可以在控制台2中执行命令“vm 31”, 查看此时应用程序进程的虚拟地址描述符信息,在应用程序释放虚拟页后,可以在控制台 2 中再 次执行命令“vm 31”,查看此时应用程序进程的虚拟地址描述符信息。
15
提示:API 函数 VirtualAlloc 定义在 api/eosapi.c 文件,此 API 函数主要调用了 EOS 内核函 数 MmAllocateVirtualMemory,在 EOS 应用程序中调用函数 VirtualAlloc 时,除了使用 MEM_RESERVE 标志外,还必须使用 MEM_COMMIT 标志;
API 函数 VirtualFree 定义在 api/eosapi.c 文件,此 API 函数主要调用了 EOS 内核函 数 MmFreeVirtualMemory,在 EOS 应用程序中调用函数 VirtualFree 时,要使用 MEM_RELEASE 标志。
3. 主要数据结构、实现代码及其说明 typedef struct _MMPFN {
ULONG Unused : 9; // 未用
ULONG PageState : 3; // 物理页的状态
ULONG Next : 20; // 下一个物理页的页框号 }MMPFN, *PMMPFN;
typedef enum _PAGE_STATE { ZEROED_PAGE, // 零页 FREE_PAGE, // 自由页 BUSY_PAGE, // 占用页 } PAGE_STATE;
// 虚拟地址描述符
typedef struct _MMVAD{
ULONG_PTR StartingVpn; // 被使用区域的开始虚页框号 ULONG_PTR EndVpn; // 被使用区域的结束虚页框号
16
LIST_ENTRY VadListEntry; // 链表项,用于将描述同一地址空间的所有VAD串成链表
}MMVAD, *PMMVAD; // 虚拟地址描述符链表
typedef struct _MMVAD_LIST{
ULONG_PTR StartingVpn; // 记录的进程地址空间的开始虚页号 ULONG_PTR EndVpn; // 记录的进程地址空间的结束虚页号 LIST_ENTRY VadListHead; // VAD链表头 }MMVAD_LIST, *PMMVAD_LIST;
四.实验体会
在本次实验中,通过调试EOS操作系统中物理存储空间和虚拟存储空间的分配和回收函数,对操作系统的内存管理机制和实现有了更进一步的认识,对于自己动手设计应用程序进程中分配虚拟页和释放虚拟页的程序,需要首先了解代码的设计思路以及各个变量所代表的含义,在实践的过程中,逐渐了解了虚拟内存分配和释放时的函数调用关系,并通过阅读函数源代码理解了具体的逻辑顺序,加深了对编程的掌握,尤其是对操作系统内存分配的简单掌握。
17