(这个问题最初是关于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注册表,则不会设置机器控制寄存器之一中的SSE启用位。
实际上,IASDM提到了这一点:
如果操作系统没有为SSE提供足够的系统级别支持,则执行SSE或SSE2指令也会生成#UD。
彼得·科德斯(Peter Cordes)向我指出了SSE OSDev wiki,它描述了如何通过同时写入CR0
和CR4
控制寄存器来启用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。最后,定制OS必须在上下文切换期间正确处理XMM寄存器,方法是在必要时进行保存和还原。
最佳答案
如果您正在运行的旧版或自定义操作系统不支持在上下文切换器上保存XMM注册表,则不会在机器控制寄存器中设置SSE启用位。在这种情况下,所有触摸xmm寄存器的指令都会出错。
我花了一点时间找到,但是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以获取链接,包括指向Intel的insn set ref手册的链接。
相关信息:Which versions of Windows support/require which CPU multimedia extensions?包含有关如何检查对AVX和AVX512的支持的详细信息(它们也引入了新的体系结构状态,因此OS必须设置一些位,否则硬件将出现故障)。它是从另一个角度来看的,但是链接应该指出如何激活/禁用AVX支持。
关于x86 - 如何为我的独立可启动代码启用SSE?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31563078/