2

我正在为操作系统开发课做作业项目。一项任务是在中断时保存 SSE 寄存器的上下文。现在,保存和恢复上下文很容易(fxsave/fxsave)。但我有测试的问题。我想将相同的样本日期放入其中一个寄存器,但我得到的只是错误中断 6。这是代码:

// load some SSE registers
struct Vec4 {
    int x, y, z, w;
} vec = { 0, 1, 2, 3 }; 


asm volatile (  "movl %0, %%eax"
        : /* no output */
        : "r"( &vec )
        :
        );
asm volatile ( "movups (%eax), %xmm0" );

我在互联网上搜索解决方案。我得到的只是它可能与有效地址空间有关。但我不知道它是什么。

4

3 回答 3

2

我发现了问题所在。必须通过设置 CR0 和 CR4 寄存器中的一些标志来启用 SSE 指令的执行。更多信息:http ://wiki.osdev.org/SSE

于 2012-03-28T00:48:11.253 回答
2

您需要使用内存操作数作为内联汇编中的约束。这比自己生成地址(正如您尝试使用运算符)并加载到寄存器中要好得多,因为如果地址是相对&的或可重定位的,后者将不起作用。rip

asm volatile ( "movups %0, %%xmm0" 
        : /* no output */
        : "m"( vec )
        :
        );

并且您需要在注册名称之前使用两个“%%”。

在此处阅读有关 gcc 约束的更多信息:http: //gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html#Simple-Constraints。标题有点误导,因为这个概念远非简单:-)

于 2012-03-27T01:12:20.800 回答
0

你让这种方式变得比它需要的更难 - 只需使用*mmintrin.h标题中的内在函数,例如

#include <emmintrin.h>

__m128i vec = _mm_set_epi32(3, 2, 1, 0);

如果您需要将它放在特定的 XMM 寄存器中,则使用上面的示例作为起点,然后生成 asm,例如使用gcc -S生成的 asm 作为您自己代码的模板。

于 2012-03-26T20:43:57.563 回答