begin process at 2010 02 09 22:15:07
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Assembleur

 > 

Divers

 > 

Débutant(e)

 > 

AT&T erreur de compilation etc...


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

AT&T erreur de compilation etc...

dimanche 15 octobre 2006 à 16:51:38 | AT&T erreur de compilation etc...

maminovadu75

Bonjour, j'aimerais me mettre a l'assembleur mais j'ai quelque problème.
voici mon code morceau de code pour trier un tableau de int : ( mélange de C/C++ et d'assembleur. )

    for(int j=0;j<SIZE;j++)
    {
        for(int k=j;k<SIZE;k++) {
            if( i[j] > i[k] ) {
                __asm("mov %0,%%eax" :: "m" (i[j]) ); // mov eax, i|j]
                __asm("mov %0,%1" : "=m" (i[j]) : "m" (i[k]) ); // mov i[j], i[k]
                __asm("mov %%eax,%0" : "=m" (i[k]) ); // mov i[k], eax
            }

        }
    }


malheureusement IDE ( Code::Blocks ) me retourne un message d'erreur :
too many memory reference for mov.
Comment faire pour résoudre cette erreur ?


merci,

dimanche 15 octobre 2006 à 18:22:48 | Re : AT&T erreur de compilation etc...

patatalo

Membre Club Administrateur CodeS-SourceS
Réponse acceptée !
salut, ce genre d'instruction est impossible pour un processeur 386+, __asm("mov %0,%1" : "=m" (i[j]) : "m" (i[k]) ); // mov i[j], i[k] tu doit soit passer par un registre (edx ou ecx) soit par la pile avec un push/pop @++
dimanche 15 octobre 2006 à 18:50:07 | Re : AT&T erreur de compilation etc...

maminovadu75

Réponse acceptée !
je doit faire comme ceci donc ?

__asm("mov %0,%%eax" :: "m" (a[j])); // mov eax, i|j]
__asm("mov %0,%%ebx" :: "m" (a[k])); // mov eax, i|j]
__asm("mov %%ebx,%0" : "=m" (a[j]) ); // mov i[k], eax
__asm("mov %%eax,%0" : "=m" (a[k]) ); // mov i[k], eax
mais bon ce code est-il simplifier au maximum ? parce que en C, si je fait
int c;
c = i[j];
i[j] = i[k] ;
i[k] = c ;

le c obtient de meilleur résultat niveau temps, 2 tableau d'entier ( 25000 case ) strictement identique, que je veux trier les tableaux
le c est plus rapide de 200 ms environ...

pourquoi :s

dimanche 15 octobre 2006 à 20:06:16 | Re : AT&T erreur de compilation etc...

patatalo

Membre Club Administrateur CodeS-SourceS
Réponse acceptée !
salut, parce que le code c est optimisé, de plus, il utilise lui meme des registres, si les registres que tu utilise sont déjà utilisés pour les itérations, il faut les sauvegarder et les restaurer -> perte de temps. @++
lundi 16 octobre 2006 à 09:37:53 | Re : AT&T erreur de compilation etc...

BruNews

Administrateur CodeS-SourceS
Réponse acceptée !
Ce qu'on peut résumer en:
Ne jamais mettre un peu d'ASM dans une fonction en C, on ne ferait qu'empêcher l'optimisation du compilo.
Soit on écrit la fonction entièrement en ASM soit on laisse en C.

ciao...
BruNews, MVP VC++
lundi 16 octobre 2006 à 10:50:21 | Re : AT&T erreur de compilation etc...

_dune2_

Membre Club
Réponse acceptée !
Salut,



Je suis d'accord avec BruNews, tant que l'on reste dans du code non vectorisable.
On peut par contre être amené (et je le fais assez souvent pour le traitement d'image ou de signal) à inserer de l'asm en ligne dans du C pour utiliser les instructions MMX et SSE, tant que le compilateur ne saura pas vectoriser à notre place (vectorisation prévu pour gcc 4.x, mais pour l'instant gcc-4.1 ne sait _que_ vectoriser et n'implémente pas encore la conversion vers MMX et SSE des boucles).

Exemple, sommation de 2 vecteurs de 16 bits signé avec gain dont la taille est multiple de 8 mots :

int audioMixer(short *mix1, int len1, short *mix2, int len2, int gain)
{
  int   len;

  //B1 GREATER THAN B2
  if (len1>len2)  {
    len=len1;
    for (int i=len2;i<len;i++)  mix2[i]=0;
  }
  else  {
    len=len2;
    for (int i=len1;i<len;i++)  mix1[i]=0;
  }

  // for SSE2 we need SSE2 cpu caps and len multiple of 8 shorts
  if((cpucaps & CPU_CAPS_SSE2) && !(len & 0x07)) {
      // go for SSE loop
      int len8 = (len+7)>>3 ;
      gain = gain & 0xFF; // ensure that gain is positive
      if(gain != 0) {
#ifdef __i386__ // to protect other archi compilation ...
    __asm(
         "   movd       %2,%%mm0      ;" // MM0 = [0 0 0 G]
         "   pshufw     $0,%%mm0,%%mm0;" // MM0 = [G G G G]
         "   movq2dq    %%mm0,%%xmm0  ;" // XMM0 = [0 0 0 0 G G G G]
         "   movdqa     %%xmm0,%%xmm1 ;" // XMM1 = [0 0 0 0 G G G G]
         "   pslldq     $8,%%xmm1     ;" // XMM1 = [G G G G 0 0 0 0]
         "   por        %%xmm1,%%xmm0 ;" // XMM0 = [G G G G G G G G]
         "0:                          ;"
         "   movdqu     (%0),%%xmm7   ;" // XMM7=Mix1
         "   movdqu     (%1),%%xmm1   ;" // XMM1=[S1 S2 S3 S4 S5 S6 S7 S8]
         "   movdqa     %%xmm1,%%xmm2 ;" // XMM2=[S1 S2 S3 S4 S5 S6 S7 S8]
         "   pmullw     %%xmm0,%%xmm1 ;" // XMM1= low words of G*S
         "   pmulhw     %%xmm0,%%xmm2 ;" // XMM2= high words of G*S
         "   movdqa     %%xmm1,%%xmm3 ;" // XMM3= low words of G*S
         "   punpcklwd  %%xmm2,%%xmm1 ;" // XMM1= [S1*G S2*G S3*G S4*G]
         "   punpckhwd  %%xmm2,%%xmm3 ;" // XMM3= [S5*G S6*G S7*G S8*G]
         "   psrad      $2,%%xmm1     ;" // XMM1= [S1*G S2*G S3*G S4*G] >> 2
         "   psrad      $2,%%xmm3     ;" // XMM3= [S5*G S6*G S7*G S8*G] >> 2
         "   packssdw   %%xmm3,%%xmm1 ;" // XMM1= [S1 S2 S3 S4 S5 S6 S7 S8]
         "   paddsw     %%xmm7,%%xmm1 ;" // Add Mix1 and Mix2*GAIN
         "   movdqu     %%xmm1,(%0)   ;" // Write result
         "   add        $16,%0        ;" // mix1 to next 8 values
         "   add        $16,%1        ;" // mix2 to next 8 values
         "   dec        %3            ;" // decrement counter
         "   jne        0b            ;" // roll if not zero
         :: "r" (mix1), "r" (mix2), "r" (gain), "r" (len8));
#endif
      }
  } else {
      // for MMX we need MMX cpu caps and len multiple of 4 shorts
      if((cpucaps & CPU_CAPS_MMX) && !(len & 0x03)) {
      int len4 = (len)>>2 ;
      gain = gain & 0xFF; // ensure that gain is positive
      // need to create mmx_gain, cause pshufw is SSE instr.
      unsigned short mmx_gain[4];
      mmx_gain[0] = gain;
      mmx_gain[1] = gain;
      mmx_gain[2] = gain;
      mmx_gain[3] = gain;
      // go for MMX loop
#ifdef __i386__ // to protect other archi compilation ...
      __asm(
            "   movq       %2,%%mm0      ;" // MM0 = [G G G G]
            "0:                          ;"
            "   movq       (%0),%%mm7    ;" // MM7=Mix1
            "   movq       (%1),%%mm1    ;" // MM1=[S1 S2 S3 S4]
            "   movq       %%mm1,%%mm2   ;" // MM2=[S1 S2 S3 S4]
            "   pmullw     %%mm0,%%mm1   ;" // MM1= low words of G*S
            "   pmulhw     %%mm0,%%mm2   ;" // MM2= high words of G*S
            "   movq       %%mm1,%%mm3   ;" // MM3= low words of G*S
            "   punpcklwd  %%mm2,%%mm1   ;" // MM1= [S1*G S2*G]
            "   punpckhwd  %%mm2,%%mm3   ;" // MM3= [S3*G S4*G]
            "   psrad      $2,%%mm1      ;" // MM1= [S1*G S2*G] >> 2
            "   psrad      $2,%%mm3      ;" // MM3= [S3*G S4*G] >> 2
            "   packssdw   %%mm3,%%mm1   ;" // MM1= [S1 S2 S3 S4]
            "   paddsw     %%mm7,%%mm1   ;" // Add Mix1 and Mix2*GAIN
            "   movq       %%mm1,(%0)    ;" // Write result
            "   add        $8,%0         ;" // mix1 to next 4 values
            "   add        $8,%1         ;" // mix2 to next 4 values
            "   dec        %3            ;" // decrement counter
            "   jne        0b            ;" // roll if not zero
            "   emms                     ;" // dont forget to cleanup FPU stack !
            :: "r" (mix1), "r" (mix2), "m" (mmx_gain[0]), "r" (len4));
#endif
      } else {
        // Fall back to standard mix
      // at first, division is VERY slow
      //for (int i=0;i<len;i++) mix1[i]=mix1[i]+((mix2[i]*gain)/GAIN_REF);
      // it is greatly better to do 2 right shifts as GAIN_REF=4
      for (int i=0;i<len;i++) {
        int result;
        result=mix1[i]+((mix2[i]*gain)>>2);
        if(result>32767) result=32767;
        if(result<-32768) result=-32768;
        mix1[i]=(short)result;
      }
      }
  }

  return len;
}

Mais pour le reste du code, standard, il est évident que le compilateur gcc est bien meilleur que nous en optimisation, et surtout dans sa capacité à réorganiser les instructions et à tirer parti des spécificités du processeur (en utilisant "-march=pentium4" par exemple).

Gentoo... que du bonheur ...
lundi 16 octobre 2006 à 18:53:19 | Re : AT&T erreur de compilation etc...

maminovadu75

savez vous ou je peux trouver une documentation très complète pour apprendre a programmer ' correctement en asm ' ?

merci de votre aide
samedi 28 octobre 2006 à 13:12:18 | Re : AT&T erreur de compilation etc...

_dune2_

Membre Club
Salut,



Je ne sais pas si tu trouveras "[..] une documentation très complète pour apprendre a programmer ' correctement en asm ' [..]".

Si je peux te donner donner une méthode qui fonctionne bien, c'est l'analogie entre la programmation en asm et le langage :

1) Pour commencer, tu apprends la grammaire de base avec des bases en orthographe. De même en assembleur, pour commencer, tu vas apprendre à écrire des routines simples (grammaire de base) avec un jeu d'instruction de base (orthographe de base).

2) Tu vas ensuite améliorer ton vocabulaire pour réaliser des phrases ayant un sens plus pointu (utilisation de termes exacts). De même en assembleur, tu vas ensuite enrichir ton jeu d'instructions, non pas avec le dico de français ;) ,mais avec les datasheets d'intel (ou de tout autre constructeur de processeur).

3) tu vas prendre de l'aisance dans la langue, et construire des phrases riches en vocabulaire et utilisant des tournures de phrases trés pointues tout en jouant avec les mots (.. stade des écrivains et artistes). Ainsi, à ce stade en tant que programmeur en asm, tu vas prendre de l'aisance en manipulation des instructions et en optimisation de code ... et tu vas devenir un virtuose de la prose assembleur ;)

Tu peux donc conclure par toi même que la programmation en assembleur (mais aussi dans les autres langages) commence par l'apprentissage des rudiments (dont tu trouveras beaucoups d'exemples via google), mais se forge ensuite sur son expérience et sa motivation à aller chercher le plus loin possible les astuces de codes ... et celà, aucune documentation ne peut te l'apprendre ;)

La programmation est une passion ....

Gentoo... que du bonheur ...


Cette discussion est classée dans : code, int, erreur, mov, eax


Répondre à ce message

Sujets en rapport avec ce message

c/c++ et 19h [ par Xs ] salut !je travaille sous VC++ et j'aimerais utiliser une interuption processeur : 19hmon code actuel marche mais au lieu d'eteindre le PC, il le fait Cycles de mov [ par vecchio56 ] Je me demandais si les instructions suivantes étaient équivalentes en termes de performances, ou si certaines d'entres elles demandaient plus de cycle FPU et puissance d'un nombre [ par AlexMAN ] Bonjour, Voila, j'ai 'codé' 2 fonctions permettant de calculer un nombre n a une puissance exp (la fonction est bourrin, cad pas de decoupages de la f Cherchez l'erreur [ par neo1012 ] Salut, J'ai commencé l'ASM il n'y a pas longtemps, et hier j'ai fait mom premier programme: jmp string code: pop ecx mov bl,1 mov dl,23 ;mov al,4 i Petit problème pour comparer (cmp) [ par smok1360 ] Bonjour à tous,Pour commencer, j'espère de ne pas avoir choisis le mauvais lieu pour poster, j'ai un petit peu hésité Donc, j'ai décidé d'apprendre l' afficher un caractère avec int 10h [ par thicdorb ] bonjour à tous,je suis débutant en assembleur et je commence par le début : afficher un caractèrej'utilise l'inteeruption BIOS 10h    mov    al, 'A'   Problème de restitution d'une chaîne. [ par Sawteeth ] Bonsoir. Je viens de débuter l'assembleur et j'ai tenté de faire un petit programme qui lit une chaîne au clavier et l'affiche à l'écran. Le problème [linux] read and open [ par sheorogath ] Bonjour,je débute un peu en assembleur et j'essaie de faire un programme qui lit le début d'un fichier dont le nom est entré par l'utilisateur.Voici l Boot et heure [ par henri12 ] je fais un essai de changement de l heure avec l interruption 21h sous le boot l heure n est pas changerpourquoi.286C   ;Code de bootsecteur permettan Une mémoire "read" [ par msteve ] Bonsoir, Je suis débutant et j'ai recopié un programme test. Je parviens à l'assembler, puis à créer un .exe ; quend je lance l'exe j'obtiens la boîte


Nos sponsors


Sondage...

Comparez les prix


HTC Hero

Entre 550€ et 550€

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,671 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales