要点回顾
通过前文简单了解了PDE、PTE,本文来了解一下PDE、PTE的属性。
物理页的属性
物理页的属性 = PDE属性 &(与运算) PTE属性
通过前文的实验可以发现,PDE与PTE的后12位,也就是二进制的低12位,是属性。其中存储的内容代表着属性。
PDE与PTE的后12位有很多是重叠的,属性类型都是一样的,只有一部分不一样。
P位
线性地址0为什么不能访问?没有指定物理页。
指定物理页就一定能访问?看PDE与PTE的P位,P = 1,才是有效的物理页。
如地址0,如果想访问的话就需要保证PDE与PTE的P位(也就是0位),与运算后的结果为1,才能访问,物理页的属性 = PDE属性 &(与运算) PTE属性。
R/W位
R/W = 0:只读。
R/W = 1:可读可写。
实验
定义一个只读类型的变量,在另一个线性地址指向相同的物理页,通过修改PDE/PTE属性,实现可写。
#include "stdafx.h"
#include <windows.h>
int main(int argc, char* argv[])
{
char* str = "Hello World";
//修改只读变量
//str[1] = 'M';
printf("线性地址:%x\n", str);
getchar();
DWORD dwVal = (DWORD)str;
*(char*)dwVal = 'M';
printf("修改后的值:%s\n", str);
return 0;
}
如果这份代码执行,那么会报错,因为hello world是常量。
是谁不让修改呢?段/页的限制,不允许它修改,因为它现在的PDE和PTE的属性是只读的,所以无法修改。
运行程序,停在getchar(),并修改PDE、PTE的读写位修改为可读写。
继续执行:
程序正常执行,没有报错。
一个只读的常量修改为了可读写的。
限制是谁呢?跟谁都没关系,只跟页有关系。