Windows内存管理学习笔记(三)—— 无处不在的缺页异常

缺页异常

描述

  1. 例:当CPU访问一个地址,其PTE的P位(页面有效位)为0,此时会产生缺页异常
  2. 在windows中,缺页异常是时刻在发生的

PTE结构(10-10-12分页)
在这里插入图片描述
假设:当我们的物理内存大小只有2MB时,当我们需要用到某个物理页的时候,将对应物理页的P位置1,当我们不再需要使用该物理页时,再将其P位置0,这样的内存使用效率是非常低的,因此windows不是这样设计的——只有正在使用的线性地址,才会被挂上物理页,当物理页在一段时间内不被使用或不够用的情况下,操作系统会将当前物理页中的数据拷贝至硬盘中,然后将当前物理页供给“别人”使用,当需要再次用到该物理页的数据时,则将“别人”的数据再拷贝出来,将“自己"的数据从硬盘中拷回,被拷至硬盘中的物理页数据会被写入到一个文件中,也就是我们平时常说的虚拟内存

实验一:设置虚拟内存

1)右键”我的电脑“-属性-高级-”性能“设置-高级
在这里插入图片描述2)将虚拟内存大小设置为780MB
在这里插入图片描述
3)查看c:\pagefile.sys文件属性(需设置文件夹选项-显示隐藏文件)
在这里插入图片描述
当物理页占用情况较为紧张时,这个文件用于存放物理页的临时数据作为备份

无处不在的缺页

描述:当线性地址对应的物理页被存储到文件中时,PTE结构被拓展为以下四种情形
在这里插入图片描述

位于页面文件

描述

  1. 当物理页被放入页面文件时,PTE结构如图a所示
  2. 当该进程再次读取该物理页对应的线性地址时,由于P位为0,因此会触发缺页异常处理程序
  3. windows xp中,缺页异常处理程序位于IDT[0xE]
  4. 此时,缺页异常处理程序会再次查询当前PTE的属性,若1-4位,5-9位,12-31位都有值,说明当前PTE是有效的,但是物理页被存放到了页面文件中
  5. 然后,缺页异常处理程序根据PTE中得到的值去查询pagefile.sys,将原来的物理页的内容挂入新的物理页,然后将P位置1,再将新的物理页的物理地址挂入PTE的第12-31位
  6. 在用户看来,两次读取同一个线性地址,中间这一系列复杂过程是透明的,而只能观察到两次都成功读取了同一个值

保留与提交的误区

我们对于VirtualAlloc的传统概念

LPVOID VirtualAlloc{
	LPVOID lpAddress,
	DWORD dwSize,
	DWORD flAllocationType, 	// 分配的类型
							// MEM_RESERVE:只保留线性地址,不分配物理页
							// MEM_COMMIT:既保留线性地址,又分配物理页
	DWORD flProtect
};

思考:如果设置flAllocationType成员的值为MEM_COMMIT,当函数执行结束之后,马上就会为当前线性地址分配物理页吗?
答案:不会,只有当线性地址真正被使用时,才会分配物理页

实验二:理解缺页异常

1)编译并运行以下代码

#include <stdio.h>
#include <windows.h>

int main()
{
	LPVOID pAddr = VirtualAlloc(NULL, 0x1000*8, MEM_COMMIT, PAGE_READWRITE);

	printf("%p\n", pAddr);

	getchar();

	*(PDWORD)pAddr = 0x12345678;

	getchar();

	return 0;
}

2)运行结果
在这里插入图片描述
3)查看pAddr所在的线性地址是否存在物理页

kd> !process 0 0

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到,此时并未被挂上具体物理页(PTE为空)

备注:上述步骤也可以使用以下命令进行代替
在这里插入图片描述

4)继续运行程序,再次查看PTE
在这里插入图片描述
在这里插入图片描述
此时线性地址被挂上物理页(PTE有值)

5)观察VadRoot
在这里插入图片描述
标红行的8指的是最多可以为这块线性地址分配8个物理页(0-7),但不是每块线性地址都已被挂上有效的物理页,只有当对应线性地址块被使用时,才会真正被挂上物理页

6)观察_MMVAD结构体
在这里插入图片描述
当访问一个未被挂上物理页的线性地址时,会触发缺页异常,缺页异常处理程序会去查找VadRoot,若当前线性地址已被分配,则会将其挂上物理页,否则会触发内存访问错误

总结:缺页异常使得物理页的使用更加高效

EXECUTE_WRITECOPY

描述:当程序正常加载一个EXE或者DLL时,其VadRoot中的内存属性为Mapped EXE,权限为EXECUTE_WRITECOPY,当试图对其某一内容进行修改时,无法对其它进程中的同一个模块产生影响

原理

  1. 当试图对其某一内容进行修改时,系统会检查其线性地址对应的物理页的PTE属性,若R/W属性为0时,触发缺页异常
  2. 缺页异常处理程序检查VadRoot中对应线性地址所在空间的MMVAD_FLAGS中的Protection成员,若值位0x111时,表示权限为EXECUTE_WRITECOPY
  3. 此时,缺页异常处理程序将当前线性地址对应的物理页内容进行拷贝,将其写入一个新的物理页,然后将当前进程需要修改的线性地址挂入新的物理页上,然后对需要修改的内容进行写入

解决方法:可通过编写驱动程序先将需要修改的线性地址对应的物理页的PTER/W位置为1,再对需要修改的地方进行修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值