关于《X86汇编语言从实模式到保护模式》这本书里面的一个疑问

ZSAIM 2017-09-22 02:18:04
在《X86汇编语言从实模式到保护模式》书上318页第三段最后一句:
“唯一没有修改的是0~4GB内存段的描述符,它本身就是为访问整个内存空间而存在的,不需要修改。”
我的问题是为什么不需要修改,开启了分页机制之后不是所有的线性地址都需要现经过分页部件转换后才能得到物理地址吗?
如果是这样的话,那么GDT中的段基地址就是线性地址,也需要经过分页部件。

所以,比如有这样两条指令
mov ebx,0x0008   ;(0~4GB段描述符的选择子是0X0008)  
mov ds,ebx

这首先通过选择子,找到0~4GB的段描述符,但是问题是,这里的段描述符中的段基地址正如上面说的那句话,没有把最高位改成1(页目录中的高2GB是映射到内核),那么自然就是线性地址 0x00000000,经过分页部件,高10为页目录索引是0,中间10位页表索引是0,低10位页表偏移也是0,可是这里对应的不一定是物理地址0x00000000 啊。。。
(因为有一个过程是:load_relocate_program,这里面就是把原来页目录底部的0x0021003清零了,后面还有很多用到0~4GB段描述符的)

希望大家能够解决我这个疑惑。

------------------------------------------------------
下面是我调试的结果:
第一张图是GDT上的内容,我所说的问题是在一号段描述符这里,里面看到线性地址是0x00000000,

下面这张图的是线性地址0x00000000所指向的并没有在页目录和页表上登记,info tab下面可以看到。

这是执行将0~4GB选择子弄进ds后的再一次页目录等表信息。


还可以执行的,但是我上面的分析有什么问题吗。。。实在想不懂,希望大家能帮我解答下
...全文
1905 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
体验太差 2020-02-29
  • 打赏
  • 举报
回复
楼主现在清楚了吧;

在开始,页目录建立在0002_0000的位置(CR3),第一个页表建立在0002_1000的位置;
然后进行重映射,将在高2G的位置建立页目录(CR3),但是第一个页目录项表还是指向
了0002_1000的页表:
mov dword [es:ebx+esi],0x00021003 <= Line 1047

4G的data段出来的基地址还是0000_0000的虚拟地址,然后结果高2G的页目录+0002_1000的页表
出来的物理地址还是0000_0000+offset;
ZSAIM 2017-10-18
  • 打赏
  • 举报
回复
搞懂了,原来是我对描述符高速缓存器理解错了。 描述符高速缓存器在GDT中读取的就是其段基地址。我以前还以为是物理地址 好了谢谢大家哈 还有INTEL的文档很有用。
ZSAIM 2017-10-11
  • 打赏
  • 举报
回复
又想了一晚还是没懂,为什么可以分开呢?也就是为什么其他段描述符把0x8000_0000当成而0-4gb描述符是当成偏移呢?是不是这两者哪里有不同可以区分这个的地方??实在想不明,还请帮帮忙。
tielian 2017-10-11
  • 打赏
  • 举报
回复

看看这图
  • 打赏
  • 举报
回复
页表是线性地址到物理地址的映射,线性地址是不分段的,不管哪个段的逻辑地址,转换后的线性地址只要在页表中有映射就可以访问(访问权限是另一回事),否则就产生缺页异常。
tielian 2017-10-11
  • 打赏
  • 举报
回复



建议哈 你去INTEL下一本手册 在第3章PROTECTED-MODE MEMORY MANAGEMENT能完美的解答你的疑问.
另外你可以试试自己写一个小的保护模式的例程序,能加强理解!如果你的程序有问题,把BOCHS的bochsout.txt这个文件打开,里面有你想要的。
ZSAIM 2017-10-11
  • 打赏
  • 举报
回复
引用 16 楼 tielian 的回复:
看看这图
嗯,看了似乎清楚了一些。之前是忽略了段部件。 但是还有点不太清楚就是: 0-4gb的偏移地址是0x8000_0000是哪里提供的这个偏移量,为什么不能是别的偏移量呢? 为什么其他的描述符没有这个偏移量。还有为什么0-4GB描述符的是FLAT模式,而其他的是多段模式呢? 难道是GDTR里面提供的偏移量吗?如果是这样为什么不给其他的描述符提供呢?。 实在不能理解。问题有点多,见谅。
ZSAIM 2017-10-10
  • 打赏
  • 举报
回复
引用 10 楼 tielian 的回复:
把源码发出来大家看看
代码就是这本书上配套的代码,内核代码太长,我放网盘里了 http://pan.baidu.com/s/1i43Dks1
tielian 2017-10-10
  • 打赏
  • 举报
回复
把源码发出来大家看看
ZSAIM 2017-10-10
  • 打赏
  • 举报
回复
引用 12 楼 tielian 的回复:
我估计你被误导了,他那个 0-4G的那个段描述符是方便管理内存 是FLAT 模式, 0x8000_0000在其他几个段描述付是基地址,对于0-4G那个描述符来说是偏移 ! 实际是指向同一个物理地址的
刚才没反应过了,知道FLAT模式是什么了,是平坦模式把。 但是呢对于你说的 “”0x8000_0000在其他几个段描述付是基地址,对于0-4G那个描述符来说是偏移 !“” 这一句不太理解,为什么是这样呢?
ZSAIM 2017-10-10
  • 打赏
  • 举报
回复
引用 12 楼 tielian 的回复:
我估计你被误导了,他那个 0-4G的那个段描述符是方便管理内存 是FLAT 模式, 0x8000_0000在其他几个段描述付是基地址,对于0-4G那个描述符来说是偏移 ! 实际是指向同一个物理地址的
听不太懂,能不能再详细一点。。。还有FLAT 模式是什么。。。
tielian 2017-10-10
  • 打赏
  • 举报
回复
我估计你被误导了,他那个 0-4G的那个段描述符是方便管理内存 是FLAT 模式, 0x8000_0000在其他几个段描述付是基地址,对于0-4G那个描述符来说是偏移 ! 实际是指向同一个物理地址的
ZSAIM 2017-10-10
  • 打赏
  • 举报
回复
引用 8 楼 Areslee 的回复:
[quote=引用 7 楼 qq405935987 的回复:] [quote=引用 6 楼 DelphiGuy 的回复:] 就你的例子截屏,“0~4GB段描述符的选择子是0X0008”,这0x0008是系统描述符,不是段描述符,你要去看它对应的0x0028选择子的描述符。
对你的这句话不是很理解。或许之前没有说清楚,我的问题是: -------------------------------------- 下图是有登记的页: 在段选择子,也就是上面截图中把0x0008赋给ds之后,通过gdtr找到gdt表上的一号描述符(上面的截图中的下面这条),,然后这个线性地址是0x00000000没错把,他不是要经过分页部件吗?既然要经过分页部件,但是实际上(上面的图中)并没有线性地址0x00000000所对应的页,他是怎么把最后的物理地址0x00000000加载到ds的描述符高速缓存器中的呢? 如果是有把GDT表中的基地址的最高位改成一后,我就可以理解,比如我要访问的是GDT中的三号段描述符,通过段选择子0x0018加载到ds中,然后找到,线性地址是0x8000b8000,很好,经过分页部件,是能找到对应的物理地址。[/quote]就是没有加载啊,因为按页表线性地址0根本就没有对应的物理地址[/quote] 如果没有加载成功他不会出现异常错误吗,为什么ds最后还能获得物理地址0x00000000?
Areslee 2017-10-09
  • 打赏
  • 举报
回复
引用 7 楼 qq405935987 的回复:
[quote=引用 6 楼 DelphiGuy 的回复:] 就你的例子截屏,“0~4GB段描述符的选择子是0X0008”,这0x0008是系统描述符,不是段描述符,你要去看它对应的0x0028选择子的描述符。
对你的这句话不是很理解。或许之前没有说清楚,我的问题是: -------------------------------------- 下图是有登记的页: 在段选择子,也就是上面截图中把0x0008赋给ds之后,通过gdtr找到gdt表上的一号描述符(上面的截图中的下面这条),,然后这个线性地址是0x00000000没错把,他不是要经过分页部件吗?既然要经过分页部件,但是实际上(上面的图中)并没有线性地址0x00000000所对应的页,他是怎么把最后的物理地址0x00000000加载到ds的描述符高速缓存器中的呢? 如果是有把GDT表中的基地址的最高位改成一后,我就可以理解,比如我要访问的是GDT中的三号段描述符,通过段选择子0x0018加载到ds中,然后找到,线性地址是0x8000b8000,很好,经过分页部件,是能找到对应的物理地址。[/quote]就是没有加载啊,因为按页表线性地址0根本就没有对应的物理地址
ZSAIM 2017-10-09
  • 打赏
  • 举报
回复
引用 6 楼 DelphiGuy 的回复:
就你的例子截屏,“0~4GB段描述符的选择子是0X0008”,这0x0008是系统描述符,不是段描述符,你要去看它对应的0x0028选择子的描述符。


对你的这句话不是很理解。或许之前没有说清楚,我的问题是:
--------------------------------------
下图是有登记的页:

在段选择子,也就是上面截图中把0x0008赋给ds之后,通过gdtr找到gdt表上的一号描述符(上面的截图中的下面这条),,然后这个线性地址是0x00000000没错把,他不是要经过分页部件吗?既然要经过分页部件,但是实际上(上面的图中)并没有线性地址0x00000000所对应的页,他是怎么把最后的物理地址0x00000000加载到ds的描述符高速缓存器中的呢?

如果是有把GDT表中的基地址的最高位改成一后,我就可以理解,比如我要访问的是GDT中的三号段描述符,通过段选择子0x0018加载到ds中,然后找到,线性地址是0x8000b8000,很好,经过分页部件,是能找到对应的物理地址。
  • 打赏
  • 举报
回复
就你的例子截屏,“0~4GB段描述符的选择子是0X0008”,这0x0008是系统描述符,不是段描述符,你要去看它对应的0x0028选择子的描述符。
tielian 2017-10-05
  • 打赏
  • 举报
回复
既然开启了分页的就应该是有对应的页表 ,再仔细看一下
Areslee 2017-10-01
  • 打赏
  • 举报
回复
没有你的环境,所以不能测试你遇到的问题 你可以试着访问一下0这个地址,如果没有对应的页目录/页表,应该会产生一个PG异常
ZSAIM 2017-09-30
  • 打赏
  • 举报
回复
可是他并没有对应的页表啊。也就是在GDT里面的段基地址,也就是线性地址,
引用 1 楼 Areslee 的回复:
是否对应物理地址就看你的页表了 段选择器用来控制代码的访问权限,具体映射的物理内存由页表负责
可是他并没有对应的页表啊。也就是在GDT里面的段基地址,也就是线性地址,并没有在也页表里面登记,看上面我的调试,里面并没有0x00000000这个所映射的物理内存。
ZSAIM 2017-09-30
  • 打赏
  • 举报
回复
可是他并没有对应的页表啊。也就是在GDT里面的段基地址,也就是线性地址,并没有在也页表里面登记,看上面我的调试,里面并没有0x00000000这个所映射的物理内存。
加载更多回复(1)

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧