2016-05-27 6 views
1

Я пытаюсь сделать добавление с помощью SSE, и я использую этот C с сборкой. Почему что-то вроде этого не работает?массив из 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 (КОД = EXC_I386_GPFLT)

Но когда вместо v1 [I], v2 [я] я ставлю v1, v2 и т.д. это работает правильно, но, конечно, только с первым элементом массива.

Что не так в моем коде?

+1

1. взгляните на сгенерированный asm, может случиться, что% 1 и% 2 передаются 'rax' /' rdx'. 2. Попробуйте передать% 1 и% 2 непосредственно с помощью 'rax' и' rdx'. Посмотрите здесь: https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints для особых ограничений x86 –

+0

Сначала я был бы склонен использовать встроенные компиляторы для 'addps'. Если вы намерены использовать встроенный ассемблер, я должен следовать рекомендациям Михала о том, чтобы заставить шаблон ассемблера выполнять большую часть работы. Предполагая, что v1, v2 и vec - все массивы векторов (__m128), тогда может работать нечто подобное: asm ( ) MOVAPS% [v1],% [out] \ n \ t " " ADDPS% [v2],% [out] \ n \ t " : [out]" = & x, m "(vec [i]) : [v1]" mx, x "(v1 [i]), [v2]" mx, x " (v2 [i]) ); ' –

+1

Ваш код, кажется, возвращает указатель на локальную переменную, которая может привести к неожиданному поведению, так как вы полагаетесь на то, что стек не разбивается после возвращения функции и перед использованием данных. –

ответ

3

Вы используете значения из таблиц (v1[i], v2[i]) и относитесь к ним как к адресам ("MOVUPS (%%rax), %%xmm0 \n"). Используйте &v1[i] и &v2[i] соответственно.

Это также почему форма v1 и v2 работает, так как в этом случае адрес передается.

+0

Большое спасибо, это очевидно, и я не видел этого. Благодаря и я спасу пару минут. – demoo