X86 多次在实际模式和保护模式之间切换的风险

X86 多次在实际模式和保护模式之间切换的风险,x86,real-mode,protected-mode,X86,Real Mode,Protected Mode,对于我的自定义引导程序项目,我多次询问自己在实模式和保护模式之间切换是否存在风险或开销。到目前为止,我一直在研究以下问题: 我知道在两种模式之间切换是可能的,我也知道如何实现这一点。我的问题仅仅集中在内核(或引导加载程序)在执行过程中多次在两种模式之间切换时可能出现的问题上 首先,我听说(和)管道中的指令可能在操作模式切换后“卡住”,导致CPU获取无效操作码。然而,我也被告知,对于较新的CPU(英特尔80386及更新版本),这不是一个问题。什么是真的?是否有其他风险或需要考虑的事项 注意

对于我的自定义引导程序项目,我多次询问自己在实模式和保护模式之间切换是否存在风险或开销。到目前为止,我一直在研究以下问题:

我知道在两种模式之间切换是可能的,我也知道如何实现这一点。我的问题仅仅集中在内核(或引导加载程序)在执行过程中多次在两种模式之间切换时可能出现的问题上

首先,我听说(和)管道中的指令可能在操作模式切换后“卡住”,导致CPU获取无效操作码。然而,我也被告知,对于较新的CPU(英特尔80386及更新版本),这不是一个问题。什么是真的?是否有其他风险或需要考虑的事项


注意:由于我的项目针对的是英特尔80386及更新版本的CPU(我当前的项目运行在英特尔i7-4770 Haswell上),我想限制我对英特尔80386开始的CPU的提问。

我可以理解内核切换模式。如果您的引导加载程序正在这样做-是要将内核复制到地址0x100000以上的块中吗?您应该始终在模式切换后执行近jmp或远jmp以刷新指令预取队列。所有80386处理器都有一个指令预取队列(尽管它们的大小可能不同),启用保护模式位后,您通常会执行一个远JMP来设置CS寄存器,以便在此时完成预取队列的刷新。如果你不做远JMP,你可以简单地对下一条指令做一个近JMP,比如
JMP flush_ipfq
,然后在下一行做
flush_ipfq:
标签。当然,在启用/禁用保护模式后,无论是否在保护模式下都可以用同样的方式解码的任何指令,在你真正这么做之前都是允许的刷新指令预取队列。一般来说,在切换后进行刷新比较容易。@MichaelFetch,所以只要使用标记32位代码开始的标签的跳转,指令预取队列就会被清除?也就是说,跳远指令(例如GAS中的
ljmp
)会自动为我执行跳远指令吗?切换回实模式也是如此?是的,远JMP(AT&T语法中的ljmp)或近JMP将自动刷新指令预检测队列。这适用于进入或退出保护模式。