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

x86 32-bits / 64-bits Assembleur Discussion :

Addition d'entier signé sur 64 bits sur un proc 32 bits


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Addition d'entier signé sur 64 bits sur un proc 32 bits
    Bonjour.

    L'environnement: P4 32 bits, Debian Squeeze, nasm, jeu d'instruction du 386.

    Sûrement qqch d'idiot, mais je ne vois pas (bien sûr...) d'où vient mon erreur.
    Mon exo:
    Soient n_1, n_2, n_3, trois entiers signés sur 64 bits.
    Mettre dans n_3 le résultat de l'opération suivante:
    [ partie entière ( n_2 / 32 ) ] * 237 + n_1

    Et voilà mon 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
     
    SECTION .data
     
        n1 DD 0x0, 0x1  
        n2 DD 0xF, 0x1  
        n3 DD 0x0, 0x0  
     
     
    SECTION .text
     
    main:
        MOVZX EAX, WORD [n2+6]; mettre la partie haute du dd en n2 dans eax, avec extension du signe
        IMUL EAX, 237; multiplier par 237
        SHL EAX, 16; décaler de 16, puisque c la partie haute
        MOV BX, WORD [n2+4]
        MUL EBX, 237;
        ADC EAX, EBX; add. à  la partie basse 
        ADD EAX, [n1]; eax + partie basse de n1 (puisque j'ai divisé par 32 n2, sa partie haute est devenue la basse)
        MOV [n3], EAX;
        MOV EAX, [n1+4] ; partie haute de n2
        ADC EAX, 0 ; eax + cf pour respecter dépassement de la dernière add
        MOV [n3+4], EAX; placer la partie haute à  la bonne place
    edit:

    Bon je pense avoir trouvé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    main:
        MOV EAX, [n2+4]; mettre la partie haute du dw en n2 dans eax, avec extension du signe
        CDQ
        IMUL EAX, 237; multiplier par 237
        ADD EAX, [n1]; eax + partie basse de n1
        MOV [n3], EAX
        ADC EDX, [n1+4] ; partie haute de n2
        MOV [n3+4], EDX; placer la partie haute a  la bonne place
    Ça foire si le produit de la partie haute de n_2 par 237 ne tient pas sur 32 bits et/ou si la somme du produit précédent et de n_1 fait de même, mais j'imagine qu'il n'y a pas moyen d'éviter ça simplement (sans structure de contrôle)?

  2. #2
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2010
    Messages : 13
    Points : 14
    Points
    14
    Par défaut
    Salut, cet exercice me rappelle quelque chose:

    Mettre dans n_3 le résultat de l'opération suivante:
    [ partie entière ( n_2 / 32 ) ] * 237 + n_1
    ne serait-ce pas n_2/2^32 ? Si oui, voici ma résolution:

    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MOV    EAX, 237
    IMUL   DWORD[N2+4]
    ADD    EAX, [N1]
    ADC    EDX, [N1+4]
    MOV    [N3], EAX
    MOV    [N3+4], EDX

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 360
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 360
    Points : 23 600
    Points
    23 600
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    main:
        MOV EAX, [n2+4]; mettre la partie haute du dw en n2 dans eax, avec extension du signe
        CDQ
    Ça ne sert à rien car le signe car est étendu à EDX, qui n'est pas impliqué dans les instructions qui suivent ;

    IMUL EAX, 237; multiplier par 237
    Il est inutile de préciser EAX dans ce cas. Lorsque seule une opérande est fournie, la multiplication est forcément effectuée avec EAX (l'accumulateur) et le mode d'adressage n'est pas le même.

    D'autre part, tu as oublié de diviser n_2 par 32. Tu peux le faire en le décalant six fois vers la droite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        ADD EAX, [n1]; eax + partie basse de n1
        MOV [n3], EAX
        ADC EDX, [n1+4] ; partie haute de n2
        MOV [n3+4], EDX; placer la partie haute a  la bonne place
    Ça foire si le produit de la partie haute de n_2 par 237 ne tient pas sur 32 bits et/ou si la somme du produit précédent et de n_1 fait de même, mais j'imagine qu'il n'y a pas moyen d'éviter ça simplement (sans structure de contrôle)?
    D'abord, je constate qu'à aucun moment, tu n'exploites la partie basse de n_2, donc le résultat sera forcément faux. Ensuite, la taille d'un produit de deux nombres peut forcément atteindre la somme des tailles des ces nombres, car 10³ × 10² = 10⁵. C'est pour cela que la multiplication de deux nombres 32 bits est stockée sur 64 bits dans le couple EDX:EAX.

    Donc, la multiplication d'un nombre 64 bits par 237 est susceptible d'en occuper 72. Si tu souhaites t'en tenir à des résultats sur 64 bits, c'est à toi de choisir des valeurs initiales qui restent dans les bornes.

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2010
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Bonjour.

    Erreur dans mon énoncé, il s'agissait bien de diviser par 2^32, ce qui explique que je n'aie pas tenu compte de la partie basse de n_2.
    Et je viens de voir que IMUL met le produit de EAX par qqch dans EDX:EAX.

    Merci.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 24/07/2013, 00h41
  2. opérateur de bits sur type signé
    Par gronaze dans le forum C
    Réponses: 6
    Dernier message: 18/09/2009, 20h05
  3. Débordement sur entier signé
    Par Jerem0101 dans le forum x86 32-bits / 64-bits
    Réponses: 2
    Dernier message: 31/10/2008, 14h30
  4. Manipulation d'un bit sur un entier
    Par SybVicious dans le forum Débuter
    Réponses: 20
    Dernier message: 31/07/2007, 00h31
  5. Réponses: 3
    Dernier message: 16/02/2007, 13h35

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