免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7541 | 回复: 19
打印 上一主题 下一主题

关于X86混合16位32位汇编编码的问题. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-10-21 00:32 |只看该作者 |倒序浏览
本帖最后由 feqin 于 2010-10-21 00:35 编辑

程序如下所示. NASM汇编..
   1  ;准备切换到保护模式
  2  mov eax,cr0
   3  or eax,1
   4  mov cr0,eax  ;真正进入保护模式
  5  jmp dword SelectofCode32:0

   程序本身是没有问题的..
基本所有资料的解释都是:"程序执行完第4行,然后一个长跳转进入32位保护模式.."
我的疑问是:当执行完第4行的时候程序应该已经是进入保护模式了,就是说接下来的取指令CS寄存器里边的内容就应该是以段选择子的形式来解释了..那么现在的问题是第5条指令是这样寻址的吗??
但是以我的分析,第5条指令寻址还是实模式时候的CS:IP..
   我很疑惑,请知道的各位帮我解答.
   万分感激..

论坛徽章:
0
2 [报告]
发表于 2010-10-21 10:36 |只看该作者
在完成实模式到保护模式转换之前,需要加载GDTR和关中断。
在第五条指令之前的CS的内容还是实模式下代码段的段值,而不是保护模式下的选择子,所以要用段间转移指令jmp。可以先定义一个宏,然后再运行这个宏指令

  1. _jmp macro sel,off
  2. db 0eah  ;jmp操作码
  3. dw off     ;16位偏移
  4. dw sel    ;选择子
  5. endm
  6. ...
  7. _jmp <sel>,<off>
复制代码

论坛徽章:
0
3 [报告]
发表于 2010-10-21 11:01 |只看该作者
回复 2# dibug


    你好像没有看明白我的意思,不过还是很感谢你回答我的问题..
    我写出的只是涉及16位和32位切换的交接处的4行代码,加载GDTR和关中断在第1行以前已经完成了..
既然第4行已经置位了PE位,那么从第5行开始(包括第5行)不就是进入保护模式了吗?保护模式的寻址不是要用段选择子吗??
我查了很多文档和代码,基本上置位PE之后接着的就是一条跳转指令,但是这条跳转指令的寻址方式是实模式的寻址方式..
所以我很困惑...
    intel文档里给出的16位和32位切换就是这个样子(置PE位,然后跳转)但是跳转指令的寻址是实模式,官方文档给出置位PE就进入了保护模式..
    我想intel的设计师不会用这么牵强的解决办法吧,可能是我在某一点上想错了..
    请各位知道的帮我解答一下,谢谢了..
    憋这么一个问题还真是寝食难安..

论坛徽章:
0
4 [报告]
发表于 2010-10-21 12:50 |只看该作者
{:3_183:}

论坛徽章:
0
5 [报告]
发表于 2010-10-22 16:00 |只看该作者
回复 3# feqin


     楼主的这个问题很有意思... 我以前写这个代码也只是按照说明来做... 只是觉得很奇怪而已...
     既然楼主翻阅Intel的文档都没有找到资料... 我也只能根据自己的理解以及逻辑推理来试着解释一下.
     首先需要提到的就是段寄存器中的非可能编程的所谓的影子寄存器。在实模式下这个影子寄存器应该也是可用的.只是不能对它编程。
    因为实模式的寻址方式是segff。这个当然与影子寄存器的值是无关的。假设这个影子寄存器中的基址应该是seg << 4,至于段长无法推测.
     如果需要起作用的话,至少是64KB。有了这个假设,从实模式到保护模式切换的那一刻一切都有很好的解释了.
     切换到保护模式.将机器状态字的最低比特位置1即可。这个指令执行之后,CPU就处于保护模式了。寻址方式也变为保护模式。
    这个时候要寻址下一条指令以及数据。寻址时就需要参考影子寄存器中的基地址。而这时候的基地址就是此时的seg << 4。外加偏移。
    当然就可以寻址下一条指令以及数据了。在重新装载CS的时候才会根据CS指定的GDT项的内容来重新装载影子寄存器。
    楼主可以试验一下...在进入保护模式之后.不改变CS的值... 看能否继续执行后续的保护模式下的指令.后续能够执行的指令长度应该是有限的...

论坛徽章:
0
6 [报告]
发表于 2010-10-23 17:33 |只看该作者
哦~~这好像就是书里说的,这条段间转移指令在实模式下被预取,保护模式下呗执行

论坛徽章:
0
7 [报告]
发表于 2010-10-23 18:39 |只看该作者
LS这位为何把教课书搬出来... 教科书里的东西不足以作为佐证...
    上次按照自己的理解回了这个帖子... 并没有实验一下...
    LS说是因为预取指令. 那我可以在进入保护模式之后...随便执行无用的指令...然后跳转继续执行这个序列指令。 如果正常指令... 可以说是与预取指令无关了吧...

  1. #say goodbye to the real mode...
  2.                 movw                $0x0001, %ax
  3.                 lmsw                %ax
  4.                 jmp                flush_instr    /* 这样能够刷新预取指令队列吧? */
  5. flush_instr:
  6.                 pushl                %eax
  7.                 pushl                %ebx
  8.                 pushl                %ecx
  9.                 pushl                %edx
  10.                 popl                %edx
  11.                 popl                %ecx
  12.                 popl                %ebx
  13.                 popl                %eax
  14.                 jmp                flush_instr
复制代码
在bochs下执行... 死循环... 我在回贴中已经提到intel涉及所谓的影子寄存器是干什么的.
即使在实模式下.这个影子寄存器肯定也是会用到的.不然每次通过总线访问内存,都要把段寄存器的值左移四位么?

论坛徽章:
0
8 [报告]
发表于 2010-10-24 23:16 |只看该作者
回复 7# PCliangtao


    你这这种验证方法不队 你的SS还是实模式下的值

论坛徽章:
0
9 [报告]
发表于 2010-10-25 14:27 |只看该作者
回复  PCliangtao


    你这这种验证方法不队 你的SS还是实模式下的值
lgj1107 发表于 2010-10-24 23:16



      你有没有看在讨论什么问题啊?

论坛徽章:
0
10 [报告]
发表于 2010-10-25 16:00 |只看该作者
回复 3# feqin


    指令是有流水线的.
第五条指令的取操作数阶段是紧接着第四条指令的取操作数阶段的,第四条指令此时还在译码阶段,也就是说还没有被执行,cpu还在实模式.而当第五条指令执行时,即cpu到保护模式下了,这时第五条指令已经进入译码阶段了,要跳转的地址当然已经取回来了.正好一条跳转,把在l1 cache中的可能预取到的仍然在实模式下寻址到的指令数据等全部清掉.这样的设计,不需要硬件多的电路,只需要软件做一点点工作就行了.很完美的设计啊.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP