2016-05-27 21 views
1

Ich versuche, etwas mit SSE hinzufügen, und ich verwende dieses C mit Assembly. Warum funktioniert so etwas nicht?Array von C in Assembly

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; 
} 

Ich habe Fehler: Thema 1: EXC_BAD_ACCESS (CODE = EXC_I386_GPFLT)

Aber wenn statt v1 [i], v2 [i] Ich habe v1, v2 usw. das funktioniert aber natürlich nur mit dem ersten element von array.

Was ist falsch in meinem Code?

+1

1. Werfen Sie einen Blick auf generierte asm es kann vorkommen, dass% 1 und% 2 von 'rax' /' rdx' übergeben werden. 2. versuche,% 1 und% 2 direkt mit 'rax' und' rdx' zu übergeben. Sehen Sie hier: https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints für x86 spezifische Einschränkungen –

+0

Zuerst würde ich geneigt sein, Compiler intrinsics für 'addps' zu verwenden. Wenn Sie Inline-Assembler verwenden möchten, befolge ich Michals Ratschlag, die Assembler-Vorlage für die meiste Arbeit zu verwenden. Angenommen, v1, v2 und vec sind alle Arrays von Vektoren (__m128), dann könnte so etwas wie folgt funktionieren: asm ( "MOVAPS% [v1],% [out] \ n \ t" "ADDPS% [v2],% [aus] \ n \ t " : [aus]" = & x, m "(vec [i]) : [v1]" mx, x "(v1 [i]), [v2]" mx, x " (v2 [i]) ); ' –

+1

Ihr Code scheint einen Zeiger auf eine lokale Variable zurückzugeben, die zu unerwartetem Verhalten führen kann, da Sie darauf vertrauen, dass der Stapel nach der Rückgabe der Funktion und vor der Verwendung der Daten nicht verworfen wird. –

Antwort

3

Sie verwenden Werte aus Tabellen (v1[i], v2[i]) und behandeln sie als Adressen ("MOVUPS (%%rax), %%xmm0 \n"). Verwenden Sie &v1[i] bzw. &v2[i].

Dies ist auch der Grund, warum das Formular v1 und v2 funktioniert, da in diesem Fall die Adresse übergeben wird.

+0

Vielen Dank, es ist offensichtlich und ich habe das nicht gesehen. Dank dir spare ich ein paar Minuten. – demoo