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 :

Décalage de bits et adresse de la variable


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut Décalage de bits et adresse de la variable
    Bonjour, j'aimerai comprendre dans le code suivant à la ligne 4 quand ont fais les décalages, par exemple
    (nTmp & 0xFF) << 8) est-ce que l'on travail toujours sur la variable nTmp à son adresse ou bien (nTmp & 0xFF) se trouve tel à un autre endroit de la mémoire même si cela me semble improbable car sa obligerai le compilateur à alloué implicitement de la mémoire à un autre endroit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    uint8_t *pPtr = malloc(sizeof(uint8_t)*2);
    pPtr[0] = 0; pPtr[1] = 1;
    uint32_t  nTmp = *(uint16_t *)pPtr;
    nTmp = (((nTmp & 0xFF) << 8) | ((nTmp & 0xFF00) >> 8));

  2. #2
    Membre émérite
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juillet 2020
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juillet 2020
    Messages : 352
    Par défaut
    Bonjour,
    alors déjà il faut se rendre compte qu'un compilateur n'est plus un simple traducteur «mot à mot» de C en code machine. Un compilo c'est bien plus intelligent que ça de nos jours. Pour t'en rendre compte tu peux essayer tes codes sur godbolt, l'explorateur de compilateurs.

    Tu remarqueras que les compilos récents ne feront rien avec ton à moins d'utiliser le résultat ; tu pourras remarquer que si le compilateur peut au moment de la compilation déterminer la valeur du résultat il le fera et au runtime tu n'auras qu'un affichage de la valeur (genre option -O3).
    Il se peut aussi (genre option -O0) qu'il reconnaisse que tu veux échanger les octets de poids forts et faibles d'un short … et qu'il le fasse sans faire aucun décalage …

    Bref, ta question est bonne mais la réponse dépend de tellement de paramètres qu'il t'est bien plus simple de tester différents compilos en différentes versions pour différentes plateformes avec différentes options pour en voir le résultat

    Bonne exploration

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Est-ce que quand tu écris nTmp + 3 tu travailles sur nTmp ?
    Non. Et les opérateurs de bit ne sont pas plus magiques et opèrent de la même manière.

    https://c.developpez.com/faq/?page=L...-operateurs-gt
    https://c.developpez.com/faq/?page=L...signifie-E1-E2
    https://c.developpez.com/faq/?page=L...signifie-E1-E2
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par hbx360 Voir le message
    Bonjour, j'aimerai comprendre dans le code suivant à la ligne 4 quand ont fais les décalages, par exemple
    (nTmp & 0xFF) << 8) est-ce que l'on travail toujours sur la variable nTmp à son adresse ou bien (nTmp & 0xFF) se trouve tel à un autre endroit de la mémoire même si cela me semble improbable car sa obligerai le compilateur à alloué implicitement de la mémoire à un autre endroit.
    Tu ne comprends pas ce qui se passe, du coups ta question n'a aucun sens. nTmp & 0x FF ne se trouve pas "ailleurs" dans la mémoire, nTmp c'est une variable, donc qui ne se trouve qu'à un endroit dans la mémoire, rien d'autre.

    Il se trouve maintenant que nTmp récupère la valeur de ce qu'il y a à l'adresse "pPtr", ok. Et alors? Qu'est-ce que cela change au point précédent? Rien. nTmp reste une variable qui vient de récupérer une valeur comme elle aurait pu en récupérer tant d'autres.

    Et ensuite tu modifies la valeur de nTmp, ok tu en as le droit. Et donc qu'est-ce que ça change? Rien. Qu'il y ait une valeur ou une autre...

    Les variables ce sont des cases et tu y mets les valeurs que tu veux. Si ces valeurs ont un sens tant mieux sinon tant pis, c'est juste toi que ça concerne.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Il se trouve maintenant que nTmp contient l'adresse d'une autre variable de ton code, ok.
    Si je lis bien le code, nTmp contient pas une adresse, car la partie droite commence par une étoile de déréférencement (et en plus il n'est pas déclaré comme pointeur) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    uint32_t  nTmp = *(uint16_t *)pPtr;
                     ^

    Citation Envoyé par hbx360 Voir le message
    Bonjour, j'aimerai comprendre dans le code suivant à la ligne 4 quand ont fais les décalages
    As-tu déjà bien compris les 3 lignes d'avant ?

    1. tu alloues de l'espace pour 2 entiers de 8 bits, qui seront côté à côté quelque part dans la mémoire
    2. tu affectes des valeurs à ces 2 entiers (à 0 et 1)
    3. tu castes le pointeur pour obtenir un pointeur vers un entier de 16 bits et tu mets la valeur pointée dans un entier de 32 bits


    Ainsi, nTmp contient ces 2 octets en poids faible, l'un à 1 et l'autre à 0. Les 16 bits de poids fort sont en tout logique à 0 aussi.

    Enfin, ligne 4, tu prends les bits de poids faibles et tu les décales de 8, les bits de poids et tu les décales de 8 dans l'autre sens, tu les assembles avec | et tu les remets dans nTmp. En gros, tu as inversé les 2 octets de poids faibles.

    Citation Envoyé par hbx360 Voir le message
    (nTmp & 0xFF) << 8) est-ce que l'on travail toujours sur la variable nTmp à son adresse ou bien (nTmp & 0xFF) se trouve tel à un autre endroit de la mémoire même si cela me semble improbable car sa obligerai le compilateur à alloué implicitement de la mémoire à un autre endroit.
    Je ne pense pas que tu puisses le deviner sans regarder le code assembleur généré par ton compilateur (ça dépend des options, du CPU, de la version du compilateur, etc). On peut s'en douter avec l'expérience et la logique, mais je ne crois que ça soit normé par le langage. En toute logique, malloc() va allouer de la mémoire sur le tas. Les autres variables vont être créées sur la pile, mais il est aussi possible qu'elles ne vivent que dans des registres du processeur, sans utiliser la pile.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Si je lis bien le code, nTmp contient pas une adresse, car la partie droite commence par une étoile de déréférencement (et en plus il n'est pas déclaré comme pointeur) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    uint32_t  nTmp = *(uint16_t *)pPtr;
                     ^
    Ah oui. J'ai lu trop vite. Je pensais que nTmp contenait une adresse mais en fait c'est encore plus simple, il contient une bête valeur.
    Ok, j'ai corrigé.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 624
    Par défaut Du code et des codes
    Bonjour,

    Hors les éléments très explicites de WhiteCrow, si nous sommes dans un cas où le compilateur doit générer un code (non pré-calculable et dont le résultat est utilisé), il n'utilisera pas de décalage mais plutôt un code assembleur de type :
    Code ASM : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mov ah,        [ptr]
    mov al,        [ptr+1]
    mov word[ptr], ax

    Il n'y a pas de gain à faire une seule lecture (genre mov dx, [ptr]) car les caches font leur travail. Le compilateur peut aussi utiliser les instructions de brassage d'octets du SSE mais cela ne semble pas valable ici.

    Il est toujours intéressant de regarder le code assembleur généré. On y trouve des choses très futées et d'autres beaucoup moins.

    Entre compilateur et CPU, c'est l'escalade du glaive et du bouclier. Les compilateurs savent très bien optimiser l'usage des instructions élémentaires mais les CPU se dotent d'instructions nouvelles qui sont de moins en moins élémentaires. Aussi, le principe du simple code pour de nombreuses instructions assembleur à optimiser se trouve mis à mal quand une seule instruction assembleur correspond à (relativement) de nombreuses lignes de code.

    Salutations

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    447
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 447
    Par défaut
    Merci pour tous vos explications et renseignements.

    @Bousk merci pour les liens ; le 1 je l'ai vue mais ne mas pas apporté la réponse que je cherchais.
    Pour le 2 il est dis : "On dit qu'on a masqué c1 avec c2. On appelle ça (c2) un masque car il permet de cacher (masquer) certains bits de c1 (cacher signifie mettre à zéro)."

    Est-ce que cela veut dire qu'on masque juste les bits de la variable sans les mettre définitivement à 0 tant qu'on ne fait pas une assignation sur la même variable ?
    Donc faire c1 = c1 & c2

    @Sve@r ça m'intéresse de savoir comment ça fonctionne.

    @Bktero oui je pense avoir bien compris les décalages et les lignes que je vous ai fourni, après c'est vraiment dans la subtilité/détail que je cherche à comprendre.

    Après sans doute que c'est dans l'optimisation fait par le compilateur que les choses se passe comme l'explique WhiteCrow.

    Dans cette exemple :

    L3 : Je pense que ce résultat doit être stocké temporairement dans la mémoire quelque part pour garder l'intégrité de la variable (nTmp) de départ.

    L4 : ici aussi je pense que c'est pareille le compilo sauvegarde le résultat temporairement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        // Je suis en Little Endian.
        L1         0100 0000 1000 0000 0000 0000 0000 0000 
        L2 & 0xFF  1111 1111 0000 0000 0000 0000 0000 0000
        ---------------------------------------------------
        L3 << 8    0100 0000 0000 0000 0000 0000 0000 0000 
        ---------------------------------------------------
        L4         0000 0000 0100 0000 0000 0000 0000 0000

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

Discussions similaires

  1. Décalage de bits
    Par Kraz dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 21/10/2006, 18h09
  2. décalages de bits
    Par seb95 dans le forum Java ME
    Réponses: 4
    Dernier message: 05/03/2006, 04h03
  3. décalage de bits
    Par cedre22 dans le forum Langage
    Réponses: 13
    Dernier message: 17/01/2006, 09h33
  4. Multiplication par décalage de bits
    Par tekman54000 dans le forum Assembleur
    Réponses: 2
    Dernier message: 25/10/2005, 11h35
  5. Décalage de bit sur unsigned char [8]
    Par dboulange dans le forum C++
    Réponses: 14
    Dernier message: 26/07/2005, 14h10

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