IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Quel code choisir entre ces deux équivalences fonctionnelles pourtant différentes en asm ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 27
    Par défaut Quel code choisir entre ces deux équivalences fonctionnelles pourtant différentes en asm ?
    Bjr,

    En faisant de la revue de code je suis tombé sur une situation équivalente à ce qui suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    int _tmain(int argc, _TCHAR* argv[])
    {
        unsigned int* pInt;
        unsigned int K=1;
     
        unsigned char* pChar;
        unsigned char C='a';
     
        pInt= &K;
        printf( "pInt : %i\n", *pInt);
        *pInt+= 1;
        printf( "pInt : %i\n", *pInt);
        (*pInt)++;
        printf( "pInt : %i\n", *pInt);
     
        pChar= &C;
        printf( "pChar : %c\n", *pChar);
        *pChar+= 1;
        printf( "pChar : %c\n", *pChar);
        (*pChar)++;
        printf( "pChar : %c\n", *pChar);
        return 0;
    }
    On obtient la sortie console suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    pInt : 1
    pInt : 2
    pInt : 3
    pChar : a
    pChar : b
    pChar : c
    Si l'on se focalise sur les incréments de valeurs pointées on obtient le code asm suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    	*pInt+= 1;
    004113EC  mov         eax,dword ptr [pInt] 
    004113EF  mov         ecx,dword ptr [eax] 
    004113F1  add         ecx,1 
    004113F4  mov         edx,dword ptr [pInt] 
    004113F7  mov         dword ptr [edx],ecx 
    	(*pInt)++;
    00411416  mov         eax,dword ptr [pInt] 
    00411419  mov         ecx,dword ptr [eax] 
    0041141B  add         ecx,1 
    0041141E  mov         edx,dword ptr [pInt] 
    00411421  mov         dword ptr [edx],ecx 
     
    	*pChar+= 1;
    00411464  mov         eax,dword ptr [pChar] 
    00411467  movzx       ecx,byte ptr [eax] 
    0041146A  add         ecx,1 
    0041146D  mov         edx,dword ptr [pChar] 
    00411470  mov         byte ptr [edx],cl 
    	(*pChar)++;
    00411490  mov         eax,dword ptr [pChar] 
    00411493  mov         cl,byte ptr [eax] 
    00411495  add         cl,1 
    00411498  mov         edx,dword ptr [pChar] 
    0041149B  mov         byte ptr [edx],cl
    Alors que les deux premiers incréments sur unsigned int* mènent à un code machine identique, leurs transpositions syntaxiques sur des unsigned char* mènent à deux séquences de code machine différentes.

    Deux questions en découlent :
    Ces dernières deux instructions sont elles vraiment équivalentes :
    Fonctionnellement parlant?
    En efficacité ? c.à.d. même nombre de cycle CPU ? 'je présume que oui, mais je ne suis pas un spécialiste de l'architecture Intel x86.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 166
    Billets dans le blog
    154
    Par défaut
    Bonjour,

    Je pense qu'ils auront la même vitesse ... car sur les processeur 32bits ... la variable et pointeur sur 32 bits et généré d'un cycle ( sur processeur 64 bits aussi )
    Les 8 bits sont aussi géré d'un trait
    Après ... pour l'histoire de différence ... il faut savoir juste qu'un char ne pourra pas dépasser 255 ... rien d'autre
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Je vais peut-être dire une bêtise, mais peut-être est-ce parce que '1' est ici considéré comme un 'int' et qu'il faut alors d'abord convertir l'objet 'char' en 'int' avant de traiter.
    Je ne sais plus ce que dit la norme au sujet d'opérations entre objets de types (char,int, etc) différents.

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 166
    Billets dans le blog
    154
    Par défaut
    Citation Envoyé par jeroman Voir le message
    Je vais peut-être dire une bêtise, mais peut-être est-ce parce que '1' est ici considéré comme un 'int' et qu'il faut alors d'abord convertir l'objet 'char' en 'int' avant de traiter.
    Je ne sais plus ce que dit la norme au sujet d'opérations entre objets de types (char,int, etc) différents.
    Je ne vois pas ce que cela va changer. Dans le code assembleur, l'addition du '1' est écrite en dur ( et c'est normal ).
    Après, peut être il y aura un gain en mémoire avec le cast ... ou même plus intelligement avec un suffixe ( 1f ... sauf que là ce n'est pas le 'f' qu'il faut ... je ne sais pas si cela existe ).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 27
    Par défaut
    En fait j'ai trouvé le tableau suivant chez Intel :



    Le premier incrément en code machine est donc effectué sur 32bits.
    Le second sur 8 bits.

    Curieusement le premier incrément est également effectué sur 32 bits lorsque l'on cast le 1 en unsigned char. C'est à dire que le code machine ne change pas.

    Dans les deux cas c'est les 8 bits les + bas qui sont remontés en mémoire.

    Je n'ai pas d'info officielle sur le nbre de cycle horloge des instructions concernées, mais je presque sûr qu'elle sont identiques.

    Le travail du compilateur me semble + fidèle à ma pensée dans le deuxième cas. Même si le résultat est strictement identique dans les deux cas.

    Merci de votre attention, et de votre patience.
    A+

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Curieusement le premier incrément est également effectué sur 32 bits lorsque l'on cast le 1 en unsigned char.
    Caster le 1 en unsigned char ne sert à rien :
    Une expression telle que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     a += b   //(a et b entiers)
    équivaut à
    sauf que a ne sera évalué qu'une fois.

    L'évaluation de cette expression commence par la promotion des "petits entiers" : la valeur des opérandes de rang inférieur à int sera convertie automatiquement en int (ou en unsigned int si la promotion en int ne permet pas de conserver la valeur).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2013] Quel est la diférence entre ces deux tableaux ?
    Par Nono Sto dans le forum Macros et VBA Excel
    Réponses: 16
    Dernier message: 22/08/2014, 16h33
  2. Réponses: 13
    Dernier message: 14/10/2008, 01h38
  3. Quelle est la différence entre ces deux déclarations ?
    Par sidahmed dans le forum Débuter
    Réponses: 15
    Dernier message: 04/10/2007, 20h59
  4. Quel est la différence entre ces deux écritures ?
    Par TocTocKiéLà? dans le forum C++
    Réponses: 5
    Dernier message: 06/08/2007, 15h11
  5. Réponses: 6
    Dernier message: 14/05/2007, 00h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo