Chinaunix

标题: 大家来讨论一下lmsw %eax开启保护模式之后处理器的寻址方式 [打印本页]

作者: PCliangtao    时间: 2010-10-25 20:14
标题: 大家来讨论一下lmsw %eax开启保护模式之后处理器的寻址方式
在CPU与编译器版有位网友提出了lmsw %eax之后一个长跳转重新装在CS及eip.  这貌似是看到的bootloader中的惯例. 我以前也只是这样想当然的按照这种方式来做。
  并没有想其中的细节。 提出的问题就是:  在置PE标志位之后.处理器处于保护模式. 之后一切所有的规则都得按照保护模式的那一套来做。这里涉及到的就是寻址方式。
   常跳转的指令以及操作数是如何获取的?   因为在处理器切换到保护模式之后,CS还没有重新加载,即使重新加载,那么重新加载CS的指令和操作数又是如何获取的呢? 这貌似是
  先有鸡还是先有蛋的问题...  有网友说是预取指。可是我实验了一下,验证这个是错误的解释。 代码很简单。

  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
复制代码
可以正常的执行... 最后肯定会异常的...呵呵...

我来说说我的观点。
  首先需要提到的就是段寄存器中的非可能编程的所谓的影子寄存器。在实模式下这个影子寄存器应该也是可用的.只是不能对它编程。
    因为实模式的寻址方式是seg << 4 + off。这个当然与影子寄存器的值是无关的。假设这个影子寄存器中的基址应该是seg << 4,至于段长无法推测.
     如果需要起作用的话,至少是64KB。有了这个假设,从实模式到保护模式切换的那一刻一切都有很好的解释了.
     切换到保护模式.将机器状态字的最低比特位置1即可。这个指令执行之后,CPU就处于保护模式了。寻址方式也变为保护模式。
    这个时候要寻址下一条指令以及数据。寻址时就需要参考影子寄存器中的基地址。而这时候的基地址就是此时的seg << 4。外加偏移。
    当然就可以寻址下一条指令以及数据了。在重新装载CS的时候才会根据CS指定的GDT项的内容来重新装载影子寄存器。
   
貌似intel文档上只说了保护模式下的影子寄存器的作用。 我想在实模式下肯定也用到了... 不然每次都需要seg << 4 + off. 这不是额外的开销么?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2