2016-05-27 1 views
1

J'essaie de faire un peu d'ajout avec SSE et j'utilise pour ce C avec l'assemblage. Pourquoi quelque chose comme ça ne fonctionne pas?tableau de C dans l'Assemblée

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

je suis arrivé erreur: Discussion 1: EXC_BAD_ACCESS (CODE = EXC_I386_GPFLT)

Mais quand au lieu de v1 [i], v2 [i] je mets v1, v2 etc. cela fonctionne correctement mais bien sûr seulement avec le premier élément de tableau.

Qu'est-ce qui ne va pas dans mon code?

+1

1. Jetez un coup d'oeil à l'asm généré, il peut arriver que% 1 et% 2 soient passés par 'rax' /' rdx'. 2. essayez de passer directement à% 1 et% 2 par 'rax' et' rdx'. Regardez ici: https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints pour les contraintes x86 spécifiques –

+0

D'abord, je serais enclin à utiliser les intrinsèques du compilateur pour 'addps'. Si vous avez l'intention d'utiliser l'assembleur en ligne, je suivrais le conseil de Michal de chercher à obtenir le modèle d'assembleur pour faire la plupart du travail. En supposant que v1, v2 et vec sont tous des tableaux de vecteurs (__m128) alors quelque chose comme ça peut fonctionner '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

Votre code semble renvoyer un pointeur vers une variable locale, ce qui pourrait provoquer un comportement inattendu puisque vous vous reposez sur le fait que la pile n'est pas saccagée après le retour de la fonction et avant l'utilisation des données. –

Répondre

3

Vous utilisez des valeurs provenant des tables (v1[i], v2[i]) et vous les traitez comme des adresses ("MOVUPS (%%rax), %%xmm0 \n"). Utilisez &v1[i] et &v2[i] respectivement.

C'est également la raison pour laquelle les formulaires v1 et v2 fonctionnent comme si l'adresse était en cours de transmission.

+0

Merci beaucoup, c'est évidemment et je n'ai pas vu ça. Merci à vous d'avoir économisé quelques minutes. – demoo