我们都知道,这段代码,会出错。为什么?都是页表起的作用。
char * msg = "Hello world!";
*msg = 'a';
实际我们在将'a'写入内存时,页表中有对应的条目,其他的数据在访问内存时的权限是R/W,既可以写也可以读。但是当'a'写入内存时,页表会发现该数据的权限是R,不可修改,MMU和页表则会发生异常,向进程发送信号,使进程终止。
32位系统下,我们的虚拟内存空间大小是4GB,一共有2^32个字节。页表一一向物理内存映射,那么耗费也是巨大的。所以会有一个页目录存储各各页表的详细信息。
虚拟地址在转换的时候并不是直接转换的,而是分为 10 + 10 + 12 来进行处理。
在将怎么将虚拟内存上的数据映射到物理内存之前,我们要说几个知识
①内存大小的基本单位是页框,大小为4KB,物理内存大小为4GB,所以就有2^20个页框。
②硬盘大小的基本单位是页帧,大小为4KB。
③IO的基本单位是4KB。
④后12位比特位的大小正好为:2^12比特 = 4KB。
由前10位比特位在页目录中找到对应页表,于是在这个页表中,由中间10位比特位找到物理内存中page的起始地址,再由后12位比特位找到物理内存中的页框中的对应准确地址。
这样做有什么好处呢?
①进程虚拟地址和物理内存的管理,通过页表+page进行解耦。
②分页机制+按需创建页表可以节省空间。