使用 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】:

您可以使用stepisi 来执行单机指令。很多其他函数都可以像这样使用-i后缀,比如nexti

【讨论】:

这就是我尝试过的,但是我在步进时看不到 gdb 中的汇编指令。它只打印出 asm-block 的最后一个结束 ')' 括号。

以上是关于使用 g++ 的 sse 内联汇编的主要内容,如果未能解决你的问题,请参考以下文章

内联汇编中的 sse 约束不起作用

GNU g++ 内联汇编块,如 Apple g++/Visual C++?

纯 C++ 代码比内联汇编程序快 10 倍。为啥?

简单 g++ 内联汇编程序中的错误

SSE2 和内联装配插入结构

GCC 内联汇编到 IAR 内联汇编