【问题标题】:array from C in Assembly汇编中来自 C 的数组
【发布时间】:2016-09-26 07:13:00
【问题描述】:

我正在尝试使用 SSE 进行一些添加,并且我正在使用这个 C 和程序集。为什么这样的事情不起作用?

struct vector {
    float x1, x2, x3, x4;
};

struct vector *dodawanie(const struct vector v1[], const struct vector v2[], int size) {

struct vector vec[size];
int i;
for(i = 0; i < size; i++) {
        asm(
            "MOV %1, %%rax \n"
            "MOV %2, %%rdx \n"

            "MOVUPS (%%rax), %%xmm0 \n"
            "MOVUPS (%%rdx), %%xmm1 \n"
            "ADDPS %%xmm0, %%xmm1 \n"

            "MOVUPS %%xmm1, %0 \n"

            :"=g"(vec[i])       //wyjscie
            :"g"(v1[i]), "g"(v2[i]) //wejscie
            :"%rax", "%rdx"
        );
}
return vec;
}

我收到错误:线程 1:EXC_BAD_ACCESS (CODE = EXC_I386_GPFLT)

但是当我把 v1[i], v2[i] 替换为 v1, v2 等时,这可以正常工作,但当然只适用于数组的第一个元素.

我的代码有什么问题?

【问题讨论】:

  • 1.看看生成的 asm 可能会发生 %1 和 %2 正在被rax/rdx 传递。 2.尝试通过raxrdx直接传递%1和%2。看这里:gcc.gnu.org/onlinedocs/gcc/… 用于 x86 特定约束
  • 首先我倾向于为addps 使用编译器内在函数。如果您打算使用内联汇编器,我会遵循 Michal 的建议,即着眼于获取汇编器模板来完成大部分工作。假设 v1、v2 和 vec 都是向量数组 (__m128),那么这样的事情可能会起作用 asm( "MOVAPS %[v1], %[out]\n\t" "ADDPS %[v2], %[out]\n\t" :[out]"=&amp;x,m"(vec[i]) :[v1]"mx,x"(v1[i]), [v2]"mx,x"(v2[i]) );
  • 您的代码似乎正在返回一个指向局部变量的指针,这可能会导致一些意外行为,因为您依赖于在函数返回后和使用数据之前堆栈不会被丢弃。

标签: c arrays x86-64 sse inline-assembly


【解决方案1】:

您正在使用表中的值(v1[i]v2[i])并将它们视为地址("MOVUPS (%%rax), %%xmm0 \n")。分别使用&amp;v1[i]&amp;v2[i]

这也是为什么表单 v1v2 在这种情况下会在传递地址时起作用。

【讨论】:

  • 非常感谢,很明显,我没有看到这个。感谢你,我节省了几分钟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-28
  • 2017-10-03
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多