如何为我的独立可启动代码启用SSE?

时间:2015-07-22 12:24:49

标签: x86 sse instruction-set

(这个问题最初是关于CVTSI2SD指令以及我认为它不能在Pentium M CPU上运行的事实,但事实上它是因为我使用自定义操作系统,我需要手动启用SSE。)

我有Pentium M CPU和自定义操作系统,到目前为止没有使用SSE指令,但我现在需要使用它们。

尝试执行任何SSE指令会导致中断6,非法操作码(在Linux中会导致SIGILL,但这不是Linux),Intel architectures software developer's manual中也提到了(我现在将其称为IASDM)为 #UD - 无效操作码(未定义操作码)

编辑:Peter Cordes确实找到了正确的原因,并向我指出了解决方案,我在下面重申:

  

如果您正在运行一个不支持在上下文切换中保存XMM reg的古老操作系统,则其中一个机器控制寄存器中的SSE使能位将无法设置。

事实上,IASDM提到了这一点:

  

如果操作系统没有为SSE提供足够的系统级支持,则执行SSE或SSE2指令也可以生成#UD。

Peter Cordes向我指出了SSE OSDev wiki,其中介绍了如何通过写入CR0CR4控制寄存器来启用SSE:

clear the CR0.EM bit (bit 2) [ CR0 &= ~(1 << 2) ]
set the CR0.MP bit (bit 1) [ CR0 |= (1 << 1) ]
set the CR4.OSFXSR bit (bit 9) [ CR4 |= (1 << 9) ]
set the CR4.OSXMMEXCPT bit (bit 10) [ CR4 |= (1 << 10) ]

请注意,为了能够写入这些寄存器,如果您处于保护模式,那么您需要处于特权级别0. The answer to this question说明如何测试它:如果处于保护模式,也就是说,当PE中的位0(CR0)设置为1时,您可以测试CS选择器中的位0和1,它们应该都是0。

最后,自定义操作系统必须在上下文切换期间正确处理XMM寄存器,方法是在必要时保存和恢复它们。

2 个答案:

答案 0 :(得分:5)

如果您运行的是不支持在上下文切换时保存XMM regs的古老或自定义操作系统,则不会在机器控制寄存器中设置SSE使能位。在这种情况下,所有触及xmm regs的指令都会出错。

我花了一秒钟才找到,但http://wiki.osdev.org/SSE解释了如何更改CR0和CR4以允许SSE指令在没有#UD的裸机上运行。

我对你的旧版本问题的第一个想法是 您可能已使用-mavx-march=sandybridge或等效编译程序,导致编译器发出所有内容的VEX编码版本。

CVTSI2SD   xmm1, xmm2/m32         ; SSE2
VCVTSI2SD  xmm1, xmm2, xmm3/m32   ; AVX

请参阅https://stackoverflow.com/tags/x86/info以获取链接,包括英特尔的insn set ref手册。

相关:Which versions of Windows support/require which CPU multimedia extensions?有一些关于如何检查对AVX和AVX512的支持的细节(这也引入了新的架构状态,因此操作系统必须设置一点或硬件故障)。它是从另一个角度来看它,但链接应指示如何激活/禁用AVX支持。

答案 1 :(得分:2)

我建议您在遇到此类问题时咨询Intel's manual

手册中明确指出CVTSI2SD是SSE2指令。