使用 g++ 的 sse 内联汇编
Posted
技术标签:
【中文标题】使用 g++ 的 sse 内联汇编【英文标题】:sse inline assembly with g++ 【发布时间】:2010-09-15 14:49:53 【问题描述】:我正在尝试 g++ 内联汇编和 sse 并编写了第一个程序。它出现段错误 - 为什么?
#include <stdio.h>
float s[128*4] __attribute__((aligned(16)));
#define r0 3
#define r1 17
#define r2 110
#define rs0 "3"
#define rs1 "17"
#define rs2 "110"
int main ()
s[r0*4+0] = 2.0; s[r0*4+1] = 3.0; s[r0*4+2] = 4.0; s[r0*4+3] = 5.0;
s[r1*4+0] = 3.5; s[r1*4+1] = 3.5; s[r1*4+2] = 3.5; s[r1*4+3] = 3.5;
asm (
"\n\t .intel_syntax noprefix"
"\n\t mov edx, s"
"\n\t movaps xmm0, [edx + " rs0 "*16]"
"\n\t movaps xmm1, [edx + " rs1 "*16]"
"\n\t mulps xmm0, xmm1"
"\n\t movaps [edx + " rs2 "*16], xmm0"
"\n\t .att_syntax"
);
printf ("%f %f %f %f\n", s[r2*4+0], s[r2*4+1], s[r2*4+2], s[r2*4+3]);
为什么 gdb 不允许我单步执行汇编指令?我需要在每一行周围写 asm ("..") 吗?
【问题讨论】:
[edx + " rs2 "*16] = [edx + 110*16] - 这不是太多了吗? (只是猜测)。 好问题,我们需要在这里进行更多组装。 IIRC GDB 没有为内联函数(ASM 或其他)设置符号。不过,不要引用我的话。 使用stepi
逐条指令。
是的,我认为这会溢出,但是编译器没有抱怨,所以我决定等待看看它是否有效,然后再看一下反汇编。当我用 3,4,5 替换 r0,r1,r2 时也会发生段错误。
【参考方案1】:
您正在将s[0]
处的数据加载到%edx
并将其用作指针。当您尝试访问%edx + 0x30
时,您会崩溃,因为s[0] + 48
没有映射到您的进程以供读取。 (具体来说,由于s
是全局的,因此初始化为全零,因此您尝试从地址0x30
加载)
【讨论】:
哦。我希望mov edx, s
立即加载地址。我会尝试找出正确的指令或语法...
您可能需要对 s 小心一点。它是一个全局符号,可能会在链接/加载时重新定位。话虽如此,我从来没有用过内联汇编器,我可能在说垃圾。
正确的语法是:offset s
- 现在它可以工作了。谢谢!
哦,它没有:它打印:7.000000 10.500000 14.000000 0.000000
...最后一个值在哪里?
@Thomas:您应该使用input/output directives / clobber lists,而不是声明数组volatile
。【参考方案2】:
您可以使用stepi
或si
来执行单机指令。很多其他函数都可以像这样使用-i
后缀,比如nexti
。
【讨论】:
这就是我尝试过的,但是我在步进时看不到 gdb 中的汇编指令。它只打印出 asm-block 的最后一个结束 ')' 括号。以上是关于使用 g++ 的 sse 内联汇编的主要内容,如果未能解决你的问题,请参考以下文章