(Pmtest8.asm总结)PagingDemoProc 注意这个这个程序段使用的是LinearAddrDemo线性地址。分页后线性地址要转换

 PagingDemoProc:
 OffsetPagingDemoProc equ PagingDemoProc - $$
 mov eax, LinearAddrDemo   ;LinearAddrDemo equ 00401000h    ,ProcFoo equ 00401000h
 call eax                              ;跳到foo处执行代码
 retf
 LenPagingDemoAll equ $ - PagingDemoProc

设计一个Flat段,尽管他的基址为0,这样做的好处是逻辑很清楚,只要用到这个段名,他们涉及到的代码和数据就都在这个段里。这样逻辑就不会混乱。

 mov eax, LinearAddrDemo   ;LinearAddrDemo equ 00401000h    ,ProcFoo equ 00401000h
 call eax   

call eax时根据cr3的页目录基址,加上LinearAddDemo的变换找到真实物理地址。

我们来看看:假设cr3中放的是PageDirBase0,即200000h,这个页目录里放的PTE为201000h

00401000 转换为2进制就是:0000,0000,0100,0000,0001,0000,0000,0000

前十位0000,0000,01,是页目录偏移量,即偏移一个页目录变为200004,则这个页目录里的PTE为202000h,存放的页为400000h

中十位0000,0000,01,是页表的偏移量,即偏移一个页表,即202004h,则这个页表PTE里页为401000h

 后12位是页偏移地址为0,所以最后的物理地址为401000h,正好是foo函数的地址,去执行foo函数。

可以参见pmtest6.asm 代码详细解释,即分页机制形成的详细过程这篇文章。

http://www.cnblogs.com/wanghj-dz/archive/2011/04/26/2029244.html

 

PSwitch函数的功能是建立好页表后,把与202004h类似的212004(由cr3不同引起的)的这个PTE里的页地址由原来的按顺序建立的00401000h,改为了00501000h,变成了bar函数的地址。这时,原来自动按顺序建立的页表就被打乱了。哈哈,妙!!

 

 再总结:终于搞清楚了,其实真实内存地址,有一块地方或n块地方存放的是对整个内存进行分配的页表。(页表就是对内存进行分配的表)也可能不止一种分配方案啊。然后在真实物理地址写上程序,以便在页表中找到程序的物理地址,从而跳转过来执行之。

 

 

 

 

posted on 2011-05-09 17:06  wanghj_dz  阅读(421)  评论(0编辑  收藏  举报

导航