(assembleur en ligne en C) Messages de l’assembleur: Erreur: pseudo-op inconnu:

J’ai écrit une courte fonction “wrapper” en C pour un assemblage en ligne asm , comme ci-dessous. Le code d’assemblage consiste en une boucle while, calculant plusieurs produits à points vectoriels à l’aide de SSE2. J’utilise GCC 4.8.4 sur Ubuntu 14.04 sur un x86. Le code suivant peut être assemblé “sans problème” sous

gcc -fpic -O2 -msse2 -S toto.c

Mais quand je fais

gcc -c foo.s

une erreur est déclenchée:

foo.c: Messages de l’assembleur:
foo.c: 2: Erreur: pseudo-op inconnu: `.while5 ‘

J’ai vérifié l’assembleur ouput “foo.s” et trouvé quelque chose d’étrange.

Fichier C “foo.c”:

#include  void foo (int kk, double *A, double *B, double *ALPHA, double *C, int ldc) { asm("movl %0, %%ecx\n\t" /* kk -> %ecx */ "movl %3, %%eax\n\t" /* A -> %eax */ "movl %4, %%edx\n\t" /* B -> %edx */ /* a while-loop */ ".while%=\n\t" "movsd (%%edx), %%xmm5\n\t" "unpcklpd %%xmm5, %%xmm5\n\t" "movapd %%xmm5, %%xmm6\n\t" "movapd (%%eax), %%xmm4\n\t" "mulpd %%xmm4, %%xmm6\n\t" "movapd 16(%%eax), %%xmm7\n\t" "addl $32, %%eax\n\t" "addpd %%xmm6, %%xmm0\n\t" "mulpd %%xmm7, %%xmm5\n\t" "addpd %%xmm5, %%xmm1\n\t" "movsd 8(%%edx), %%xmm6\n\t" "addl $16, %%edx\n\t" "unpcklpd %%xmm6, %%xmm6\n\t" "mulpd %%xmm6, %%xmm4\n\t" "addpd %%xmm4, %%xmm2\n\t" "mulpd %%xmm6, %%xmm7\n\t" "addpd %%xmm7, %%xmm3\n\t" "subl $1, %%ecx\n\t" /* kk-- */ "testl %%ecx, %%ecx\n\t" /* kk = 0 ? */ "jne .while%=\n\t" /* other input operands passing */ "movl %5, %%ecx\n\t" /* C -> %ecx */ "movl %1, %%eax\n\t" /* ALPHA -> %eax, then C0 -> %eax */ "movl %2, %%edx\n\t" /* ldc -> %edx */ /* write-back */ "movsd (%%eax), %%xmm7\n\t" "unpcklpd %%xmm7, %%xmm7\n\t" "leal (%%ecx,%%edx,8), %%eax\n\t" /* C0=C+ldc */ "mulpd %%xmm7, %%xmm0\n\t" "addpd (%%ecx), %%xmm0\n\t" "movapd %%xmm0, (%%ecx)\n\t" "mulpd %%xmm7, %%xmm2\n\t" "addpd (%%eax), %%xmm2\n\t" "movapd %%xmm2, (%%eax)\n\t" "mulpd %%xmm7, %%xmm1\n\t" "addpd 16(%%ecx), %%xmm1\n\t" "movapd %%xmm1, 16(%%ecx)\n\t" "mulpd %%xmm7, %%xmm3\n\t" "addpd 16(%%eax), %%xmm3\n\t" "movapd %%xmm3, 16(%%eax)\n\t" : /* no output operands */ : "m"(kk), "m"(ALPHA), "m"(ldc), "m"(A), "m"(B), "m"(C) /* input operands */ : "eax", "edx", "ecx", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" /* clobbers */ ); } 

sortie de l’assembleur (la boucle while semble étrange!)

 .LFB503: .cfi_startproc #APP # 4 "foo.c" 1 movl 4(%esp), %ecx movl 8(%esp), %eax movl 12(%esp), %edx .while5 movsd (%edx), %xmm5 unpcklpd %xmm5, %xmm5 movapd %xmm5, %xmm6 movapd (%eax), %xmm4 mulpd %xmm4, %xmm6 movapd 16(%eax), %xmm7 addl $32, %eax addpd %xmm6, %xmm0 mulpd %xmm7, %xmm5 addpd %xmm5, %xmm1 movsd 8(%edx), %xmm6 addl $16, %edx unpcklpd %xmm6, %xmm6 mulpd %xmm6, %xmm4 addpd %xmm4, %xmm2 mulpd %xmm6, %xmm7 addpd %xmm7, %xmm3 subl $1, %ecx testl %ecx, %ecx jne .while5 movl 20(%esp), %ecx movl 16(%esp), %eax movl 24(%esp), %edx movsd (%eax), %xmm7 unpcklpd %xmm7, %xmm7 leal (%ecx,%edx,8), %eax mulpd %xmm7, %xmm0 addpd (%ecx), %xmm0 movapd %xmm0, (%ecx) mulpd %xmm7, %xmm2 addpd (%eax), %xmm2 movapd %xmm2, (%eax) mulpd %xmm7, %xmm1 addpd 16(%ecx), %xmm1 movapd %xmm1, 16(%ecx) mulpd %xmm7, %xmm3 addpd 16(%eax), %xmm3 movapd %xmm3, 16(%eax) # 0 "" 2 #NO_APP ret .cfi_endproc 

Quelqu’un peut-il me faire savoir ce qui s’est passé? Je ne pense pas que ce soit le problème de mon compilateur. Il doit y avoir quelque chose qui ne va pas avec mon code. THX!

Étant donné que votre nom- .while n’est pas défini comme une étiquette, il est considéré comme un pseudo-op [inexistant].

Changement:

 ".while%=\n\t" 

Dans:

 ".while%=:\n\t" 

METTRE À JOUR:

Selon votre demande.

Un “pseudo-op” est une [terminologie pour] une directive assemblée qui ne correspond à aucune instruction.

Quelques exemples:

.globl main pour spécifier que l’étiquette main est une variable globale.

.text pour spécifier que ce qui suit doit être placé dans le segment “text” (de même pour .data ).

Le . préfixe est [généralement] réservé aux pseudo-opérations. C’est pourquoi vous avez le message Error: unknown pseudo-op: .

Si vous aviez fait "while%=\n\t" place [toujours faux parce qu’il n’y avait pas : dénoter une étiquette], vous auriez reçu un message différent: Error: no such instruction: