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 à droite


Sujet :

C

  1. #1
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 22
    Par défaut Décalage à droite
    Bonjour a tous

    La fonction suivante fait un décalage a droite de n bits dans un mot de 64 bit
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    static inline Word64 SAR64(Word64 x, int n)
    {
            unsigned int xLo = ((unsigned int *)&x)[0];
            int xHi = ((int *)&x)[1];
            unsigned char nb = (unsigned char)n;
     
            if (n < 32) {
                       __asm {
                                 mov edx, xHi
                                 mov eax, xLo
                                 mov cl, nb
                                 shrd eax, edx, cl
                                 sar edx, cl
                                 }
     
     
              } else if (n < 64) {   */
                       /* sar masks cl to 0x1f */
                        /*__asm {
                                  mov edx, xHi
                                  mov eax, xHi
                                  mov cl, nb
                                  sar edx, 31
                                  sar eax, cl
                                     }
                     } else {
                                __asm {
                                          sar xHi, 31
                                          mov eax, xHi
                                          mov edx, xHi
                                          }
                              }
           
    }
    Pouvez m'aidez a traduire cette fonction en C

    Merci d'avance

  2. #2
    Membre très actif
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Billets dans le blog
    1
    Par défaut
    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
     
    ;assume param1, param2=qword to shift
    ;assume param3=qword shift value
    ;assume escuze c'est une habitude, j'ecrit toujour en anglais dans les codes sources
    sarC:
    mov ebp,esp
    mov ecx,[ebp-4]
    mov eax,[ebp-12]
    mov edx,[ebp-8]
    cmp ecx,32
    jl .32
    .64:
    nia nia nia
    ret
    .32:
    nia nia nia 32
    ret
    ensuite, il faut compiler et inclure le binaire dans le code C, pour ça, je peu rien pour toi, je ne code pas en C, question d'hetique personnelle.

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 82
    Par défaut
    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
    26
    27
     
    /*
    - un exemple qui n'utilise pas UNIT64 ou __int64
    - volontairement et intégralement écrit en C
    - fonctionne avec un nombre quelconque de décalages (y compris 0)
    */
     
    struct ent64
    {
    	int fort;
    	int faible;
    }
     
    void decaleAdroite(ent64* valeur, int nb)
    {
    	int temoin;
     
    	nb &= 0x3F;	// prudence : pas plus de 63 décalages
     
    	for(b = 0; b < nb; b++)
    	{
    		temoin = valeur.fort & 0x00000001;
    		valeur.fort >>= nb;
    		valeur.faible >>= nb;
    		valeur.faible |= temoin;
    	}
    }
    Sinon "qui perd sa langue perd son âme"; il ne saurait y avoir d'éthique sans rigueur et sans respect de soi et de sa culture (donc de sa langue).

  4. #4
    Membre très actif
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Billets dans le blog
    1
    Par défaut
    pourquoi pas plus de 63 decalages?
    en asm, on peu faire autant de decalages que l'on veu. ce qui a pour effet d'effacer la donnée.

    puis, je ne vois pas ce que vien faire du c chez mr asm

  5. #5
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Bonjour,

    Citation Envoyé par edfed Voir le message
    pourquoi pas plus de 63 decalages?
    en asm, on peu faire autant de decalages que l'on veu. ce qui a pour effet d'effacer la donnée.
    D'accord, mais il ne faut pas oublier que quoi qu'il arrive, le processeur fait un masque sur le décalage.

    En 32 bits, on reste limité à une limite de 5 bits armés pour le décalage (11111b = 0x1F = 31) :

    Citation Envoyé par Manuel Intel
    IA-32 processors (starting with the Intel 286 processor) do mask the shift count to 5 bits, resulting in a maximum count of 31. This masking is done in all operating modes (including the virtual-8086 mode) to reduce the maximum execution time of the instructions.
    En 64 bits, la taille par défaut des instructions de décalage reste de 32 bits (donc, limite à 5 bits armé), sauf avec un préfixe REX.W qui passe l'instruction à 64 bits. Dans ce cas là, le processeur fait un masque sur le décalage et la limite s'établit à 6 bit armés (111111b = 0x3F = 63)

    Citation Envoyé par Manuel Intel
    The count is masked to [...] 6 bits if in 64-bit mode and REX.W is used)
    Le masque fait par Stabia me paraît légitime du fait que ça reste en adéquation avec ce que ferait le proco sur un QWORD, d'autant plus qu'en C ou C++, ça évite à la boucle de mouliner pour rien au delà de 63.

  6. #6
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 22
    Par défaut Bonjour
    merci a vous tous

    Stabia pouvez vous me dire comment trouver les 32 bits du poids fort et les 32 bits du poids faible en utilisant le type long long au lieu de la structure ent64

    merci d'avance

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 82
    Par défaut faire ou aider ?
    1/ en assembleur c'est enfantin (nous sommes sur un forum ASM)

    2/ en C cela va dépendre de ce que votre compilateur accepte et de votre machine (32 ou 64 bits)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UNIT64 valeur64 = 0x123456789ABCDEF0;
    UINT64 provisoire;
    int resultat:
     
    provisoire = valeur64;
    provisoire >>= 32;
    resultat = (int) provisoire;
    OU (microsoft par exemple, mais interdit en aéronautique !)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    resultat = (int) (provisoire >> 32);
    3/ je ne sais pourquoi vous avez besoin de cela, mais si vous êtes étudiant s'enquérir de la solution n'est pas une bonne méthode : un jour ou l'autre vous serez confronter à une réalité plus rude.

  8. #8
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 22
    Par défaut
    Voila mon code je pense que sa marche pas pour un décalage >31 bits ce code

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    typedef long long Word64;
     
    static inline Word64 sar64(Word64 valeur, int nb)
    { int temoin,b;
      Word64 provisoir;
      unsigned int poidfort,poidfaible;
     
       provisoir=valeur;
       provisoir>>=32;
       poidfort=(int)provisoir;
     
       provisoir=valeur;
       poidfaible=(int)provisoir;
     
     
     
    	nb &= 0x3F;	// prudence : pas plus de 63 décalages
     
    	for(b = 0; b < nb; b++)
    	{
    		temoin = poidfort & 0x00000001;
    		poidfort >>= nb;
    		poidfaible >>= nb;
    		poidfaible |= temoin;
     
    	}
     
     
            provisoir=0;
            provisoir=poidfort;
            provisoir<<=32;  
            provisoir+=poidfaible;
     
            return provisoir;
    }
    Si quelqu'un peut me suggérer des modification
    merci

  9. #9
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 22
    Par défaut
    Citation Envoyé par Stabia Voir le message
    1/ en assembleur c'est enfantin (nous sommes sur un forum ASM)

    2/ en C cela va dépendre de ce que votre compilateur accepte et de votre machine (32 ou 64 bits)

    UNIT64 valeur64 = 0x123456789ABCDEF0;
    UINT64 provisoire;
    int resultat:

    provisoire = valeur64;
    provisoire >>= 32;
    resultat = (int) provisoire;

    OU (microsoft par exemple, mais interdit en aéronautique !)

    resultat = (int) (provisoire >> 32);

    3/ je ne sais pourquoi vous avez besoin de cela, mais si vous êtes étudiant s'enquérir de la solution n'est pas une bonne méthode : un jour ou l'autre vous serez confronter à une réalité plus rude.
    1)Moi je développe sur ARM
    2)ARM accepte les valeurs en 64 bits
    3)Je suis pas étudiant mais faute de temps j'ai pas pu me concentrer sur ce code,en plus je maitrise pas bien l'assembleur PC.
    A chaque un sa spécialité

  10. #10
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 22
    Par défaut
    Sa marche pas

  11. #11
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 22
    Par défaut
    Citation Envoyé par doomtn Voir le message
    Voila mon code je pense que sa marche pas pour un décalage >31 bits ce code

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    typedef long long Word64;
     
    static inline Word64 sar64(Word64 valeur, int nb)
    { int temoin,b;
      Word64 provisoir;
      unsigned int poidfort,poidfaible;
     
       provisoir=valeur;
       provisoir>>=32;
       poidfort=(int)provisoir;
     
       provisoir=valeur;
       poidfaible=(int)provisoir;
     
     
     
    	nb &= 0x3F;	// prudence : pas plus de 63 décalages
     
    	for(b = 0; b < nb; b++)
    	{
    		temoin = poidfort & 0x00000001;
    		poidfort >>= nb;
    		poidfaible >>= nb;
    		poidfaible |= temoin;
     
    	}
     
     
            provisoir=0;
            provisoir=poidfort;
            provisoir<<=32;  
            provisoir+=poidfaible;
     
            return provisoir;
    }

  12. #12
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    J'en profite pour recoller ce code (voir les fonctions shl et shr pour les décalages). Si quelque chose t'échappes, n'hésites pas à poser des questions.

    Code c : 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    /* 
     
    A compiler avec -std=c99
     
    On supposera ici qu'un long long tient exactement sur 64 bits
    pour que les fonctions lsd et msd soit sémantiquement correctes.
     
    */
     
     
    #include <stdio.h>
    #include <stdlib.h>
     
     
    /* shift left */
    inline long long shl (long long x, unsigned char bitcount);
    /* shift right */
    inline long long shr (long long x, unsigned char bitcount);
    /* most significant 32 bits (dword) */
    inline int msd (long long x);
    /* less significant 32 bits (dword) */
    inline int lsd (long long x);
     
    int main(void)
    {
        long long x = 0xA12345674LL;
        unsigned char  bitcount = 4;
     
        /* Attention !!! : spécificateur de format MinGW pour long long !!! */
        printf("Nombre : %I64X\n", x);
        printf("Nombre décalé vers la gauche de 4 bits : %I64X\n", shl(x, bitcount));
        printf("Nombre décalé vers la gauche de 4 bits : %I64X\n", shr(x, bitcount));
        printf("32 bits de la partie haute : %08X\n", msd(x));
        printf("32 bits de la partie basse : %08X\n", lsd(x));
     
        return 0;
    }
    inline long long shl (long long x, unsigned char bitcount)
    {
        bitcount &= 0x3F;
        return (x << bitcount);
    }
     
    inline long long shr (long long x, unsigned char bitcount)
    {
        bitcount &= 0x3F;
        return (x >> bitcount);
    }
     
    inline int msd (long long x)
    {
        return (x >> 32);
    }
     
    inline int lsd (long long x)
    {
        return (x & 0xFFFFFFFF);
    }

  13. #13
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 22
    Par défaut
    Citation Envoyé par Neitsa Voir le message
    J'en profite pour recoller ce code (voir les fonctions shl et shr pour les décalages). Si quelque chose t'échappes, n'hésites pas à poser des questions.

    Code c : 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    /* 
     
    A compiler avec -std=c99
     
    On supposera ici qu'un long long tient exactement sur 64 bits
    pour que les fonctions lsd et msd soit sémantiquement correctes.
     
    */
     
     
    #include <stdio.h>
    #include <stdlib.h>
     
     
    /* shift left */
    inline long long shl (long long x, unsigned char bitcount);
    /* shift right */
    inline long long shr (long long x, unsigned char bitcount);
    /* most significant 32 bits (dword) */
    inline int msd (long long x);
    /* less significant 32 bits (dword) */
    inline int lsd (long long x);
     
    int main(void)
    {
        long long x = 0xA12345674LL;
        unsigned char  bitcount = 4;
     
        /* Attention !!! : spécificateur de format MinGW pour long long !!! */
        printf("Nombre : %I64X\n", x);
        printf("Nombre décalé vers la gauche de 4 bits : %I64X\n", shl(x, bitcount));
        printf("Nombre décalé vers la gauche de 4 bits : %I64X\n", shr(x, bitcount));
        printf("32 bits de la partie haute : %08X\n", msd(x));
        printf("32 bits de la partie basse : %08X\n", lsd(x));
     
        return 0;
    }
    inline long long shl (long long x, unsigned char bitcount)
    {
        bitcount &= 0x3F;
        return (x << bitcount);
    }
     
    inline long long shr (long long x, unsigned char bitcount)
    {
        bitcount &= 0x3F;
        return (x >> bitcount);
    }
     
    inline int msd (long long x)
    {
        return (x >> 32);
    }
     
    inline int lsd (long long x)
    {
        return (x & 0xFFFFFFFF);
    }
    Merci Neitsa
    Finalement je crois que je vais utilisé l'opérateur >>.
    J'ai juste une dernière question, de point de vue performance(temps d'execution...) est ce qu'il y a une grande différence entre la version en assembleur et la version en C ?

  14. #14
    Membre averti
    Inscrit en
    Janvier 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 17
    Par défaut
    Il ne faut pas oublier le unsigned long long.
    Le signe n'est jamais marrant dans les décalages, d'autant plus que le code initial était non signé.

Discussions similaires

  1. Problème de décalage à droite d'un tableau
    Par vergezzois dans le forum Débuter
    Réponses: 4
    Dernier message: 02/11/2011, 08h54
  2. Décalage sous menu à droite IE
    Par doc51 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 05/11/2009, 14h57
  3. Problème de DIV et CSS, décalage vers la droite et en haut
    Par alexis1975 dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 06/05/2009, 18h58
  4. Mes pages bougent, décalage droite/gauche
    Par kerna dans le forum Débuter
    Réponses: 10
    Dernier message: 14/04/2009, 10h28
  5. Décalage à gauche/droite
    Par Tic_et_Tac dans le forum Ada
    Réponses: 2
    Dernier message: 21/04/2008, 14h22

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