这个问题最初是关于CVTSI2SD
指令以及我认为它在Pentium M CPU上不起作用,但实际上是因为我使用了自定义操作系统,需要手动启用SSE。
我有一个Pentium M CPU和一个自定义操作系统,到目前为止没有使用过任何SSE指令,但现在我需要使用它们。
尝试执行任何SSE指令会导致中断6,非法操作码(在Linux中会导致SIGILL
,但这不是Linux),在Intel architectures software developer's manual(从现在开始我将称之为IASDM)中也称为#UD - Invalid Opcode (UnDefined Opcode)。
编辑: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。此问题的答案解释了如何测试它:(此链接)如果在保护模式下,也就是当
CR0
中的位0(PE
)设置为1时,然后可以从CS
选择器中测试位0和位1,它们应该都是0。最后,自定义操作系统必须在上下文切换期间正确处理XMM寄存器,必要时保存并恢复它们。
SIGILL
(“非法指令”)还是其他原因? - Paul R