我正在为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" );
我在互联网上搜索解决方案。我得到的只是它可能与有效的地址空间有关。但我不知道它是什么。
答案 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作为您自己代码的模板。