pmtest8.asm的功能,先执行某个线性地址处的模块,然后通过改变cr3来转换地址映射关系,再执行同一个线性地址处的模块,由于地址映射已经改变,所以两次得到的应该是不同的输出
LABEL_DESC_FLAT_C: Descriptor 0, 0fffffh,DA_CR|DA_32|DA_LIMIT_4K ;0-4G
LABEL_DESC_FLAT_RW: Descriptor 0, 0fffffh,DA_DRW|DA_LIMIT_4K ;0-4G
用两个描述符来描述这个段,因为我们不仅仅要读写这段内存,而且要执行其中的代码,而这对
描述符的属性要求是不一样的,这两个段的段基址都是零,长度是4GB
SetupPaging:
根据内存大小获得页表个数进行分页 段首地址SelectorFlatRW
分页起始地址依然是从0开始,只是页目录表、页表地址变成了PageDirBase0 PageTblBase0
PagingDemo:
主要功能是将显示FOO字符的代码片 复制到指定的位置ProcFoo 0x00401000h
将显示BAR字符的代码片 复制到指定位置ProcBar 0x00501000h
将ProcPagingDemo代码复制到0x00301000
接下来四个call是重点
1 call SetupPaging开始分页
2 call SelectorFlatC:ProcPagingDemo 开始运行301000处的代码
3 call PSwitch 切换页目录 改变地址映射
4 call SelectorFlatC:ProcPagingDemo 再次运行301000处的代码
第二步 由于此时没有切换目录,运行代码就是301000处的代码,这里是被复制的PagingDemoProc:
核心代码:mov eax, LinearAddrDemo
call eax
就是在调用LinearAddrDemo
然而 LinearAddrDemo equ 00401000h
所以直接跳转 去运行401000h处的代码,即显示FOO
PSwitch:
根据内存大小获得页表个数进行分页 段首地址 SelectorFlatRW 是一致的
页目录表是PageDirBase1 页表地址是PageTblBase1
分页之后 找到LinearAddrDemo所对应的页表,将页表中的访问页的地址换掉 原来访问页的地址内部是FOO的地址
现在换了 里面是跳转到BAR的地址
这样完成了同一个地址 确实访问了两处代码