(这个问题最初是关于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,其中介绍了如何通过写入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。
最后,自定义操作系统必须在上下文切换期间正确处理XMM寄存器,方法是在必要时保存和恢复它们。
答案 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指令。