加载SSE寄存器

时间:2012-03-26 20:06:39

标签: gcc assembly sse osdev

我正在为OS开发课做家庭作业项目。一个任务是在中断时保存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" );

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

3 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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

#include <emmintrin.h>

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

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