现代x86处理器在实模式下运行时,是否支持流水线/乱序执行?

3
在现代的x86处理器上运行启动加载程序时,处理器将处于实模式。它的指令流水线功能在实模式下是否激活?

我在询问开机时是否可以在实模式下使用流水线技术。 - Lakshman Siddartha
1个回答

4
是的,现代微架构中的乱序核心在不同模式下基本上操作相同。大部分差异在于解码器。有关现代CPU内部实际工作方式的详细信息,请参见Agner Fog的微架构pdf标签Wiki中的其他链接。
在16位模式下表现不同可能需要额外的硅片,因为它与禁用分页的32位模式非常相似,但具有不同的默认地址大小和操作数大小。
我已经阅读过AMD CPU在段具有非零基址时略微较慢。(或者我猜在16位模式下:当段寄存器本身被设置为非零值时,因为在16位模式下它们直接使用,而不是用作描述符的选择器。)

请记住,很多常见的16位习语像loop都很糟糕

此外,如果不小心处理,部分寄存器减速可能会轻易地干扰乱序执行。Intel P6系列和SnB系列CPU单独重命名部分寄存器,因此写入AX不会对EAX / RAX的全部内容产生虚假依赖关系。在SnB之前的CPU上合并时可能会出现停顿,或者在Haswell之前的SnB上稍微减慢。

所有其他微架构都将mov ax,5视为对eax进行读取-修改-写入,因此它不会打破旧值ax的依赖链。如果不小心处理,这可能会对乱序执行造成巨大问题。

请阅读Agner Fog的手册以了解更多信息。

16位寻址模式可能表现不佳,我忘记了。32位代码不需要它们快速,64位代码根本不能使用16位地址。(64位代码中的地址大小前缀意味着地址大小= 32位。)


VEX编码指令(包括所有AVX和一些BMI1和BMI2整数指令,如 blsrpext)在实模式或VM86模式下不可用。这个英特尔论坛主题(失效链接1表明,这可能是由于现有软件(NTVDM)将机器代码用作陷阱进入保护模式造成的。(即与VEX使用相同的LDS/LES非法操作数)。因此,使VEX编码指令仍然生成 #UD 对于向后兼容性非常重要。迈克尔·佩奇发表了评论:

0xc4 0xc4 0x60(Vm版本号)和0xc4, 0xc4, 0x58在90年代中期的16位代码中非常常见,甚至在NTVDM之前就已经被广泛使用。它们通常被我们这些试图确定是否在SoftPC中运行的人所使用。当时它们作为BOP代码被稀疏地记录下来。微软在90年代中期通过NT设备驱动程序包对它们进行了半文档化处理。这并不奇怪,因为NTVDM是基于SoftPC的。我找出了旧的NT DDK CD,并在文件ISVBOP.h中找到它们。

虽然如此,在实模式下仍然可以使用SSE,如果您使用正确的CR设置启用它

(VEX/EVEX在16位保护模式下可用,但不适用于实模式或虚拟8086模式。 x86 32位汇编代码是否有效的x86 64位汇编代码?)


脚注1:链接失效,未在wayback机器中存档。英特尔可能只是重新组织了他们的论坛URL,但我没有去查找。

2
我总能从阅读您的答案中学到很多东西,即使我已经知道问题的答案! :) 例如,我不知道VEX编码指令在实模式下不可用。 - Cody Gray
@CodyGray:如果答案不涉及相关信息,SO将会是一个相当无聊的地方:D。我一直想弄清楚为什么某些指令在实模式下不可用。指令集手册记录了一些BMI/BMI2整数指令的情况,但并未记录AVX2指令(如VPBLENDD)的情况。直到写这篇答案时进行搜索,我才确定。我想知道它是否与16位操作数大小不可用有关,并且忽略操作数大小前缀而不需要一个将需要晶体管。 - Peter Cordes
2
0xc4 0xc4 0x60(Vm版本号)和0xc4、0xc4、0x58在90年代中期16位代码中非常常见,甚至在NTVDM之前就已经被广泛使用了。它们通常被我们这些试图确定是否在SoftPC中运行的人所使用。当时它们作为BOP代码被稀疏地记录下来。微软在90年代中期通过NT设备驱动程序套件对它们进行了半文档化。这并不令人意外,因为NTVDM是基于SoftPC开发的。我找出了旧的NT DDK CD,并在文件ISVBOP.h中找到了它们。 - Michael Petch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接