【问题标题】:sse inline assembly with g++使用 g++ 的 sse 内联汇编
【发布时间】: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 时也会发生段错误。

标签: c++ c g++ inline-assembly sse


【解决方案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 的最后一个结束 ')' 括号。
猜你喜欢
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 2016-08-15
  • 1970-01-01
  • 2012-10-20
  • 2012-05-05
相关资源
最近更新 更多