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 :

Comparer les valeurs en assembleur.


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Novembre 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Novembre 2018
    Messages : 22
    Points : 12
    Points
    12
    Par défaut Comparer les valeurs en assembleur.
    Bonjour, je cherche à comparer 2 valeurs en assembleur 32 bits x86. La première valeur correspond à l'input de l'utilisateur : je le récupere et convertis en entier. La deuxième valeur est une constante.

    J'ai déjà essayé plusieurs trucs mais ca ne marche pas. On dirait que le programme ne fait pas correctement la comparaison.

    Essai 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mov eax, choix
               cmp eax, 255
               ja _plusgrand
    Essai 2 :
    .data
    max: db 255
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    mov eax, [choix]
               mov ebx, [max]
               cmp eax, ebx
              ja _plusgrand
    J'espère que quelqu'un puisse m'expliquer. Merci

  2. #2
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    Mars 2008
    Messages
    314
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : Mars 2008
    Messages : 314
    Points : 550
    Points
    550
    Par défaut
    dans l'essai 1 tu met l'adresse de la variable choix dans eax, du coup ça ne peut que louper

    dans l'essai 2 tu définis max comme étant un octet, du coup tu charge en plus de max les trois octet de données qui sont après lors de l'instruction "mov ebx,[max]"

  3. #3
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Novembre 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Novembre 2018
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par bifur Voir le message
    dans l'essai 1 tu met l'adresse de la variable choix dans eax, du coup ça ne peut que louper

    dans l'essai 2 tu définis max comme étant un octet, du coup tu charge en plus de max les trois octet de données qui sont après lors de l'instruction "mov ebx,[max]"
    Comment je vais devoir procéder alors ? Je bloque sur ce truc depuis 4 jours

  4. #4
    Membre du Club
    Homme Profil pro
    Ceo
    Inscrit en
    Décembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Ceo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 25
    Points : 44
    Points
    44
    Par défaut comparaison de valeur en assembleur
    Bonjour Neo Craft, En fait, comme l' a si bien dit bifur, il faut effectivement faire la différence entre adresse et valeur. Si tu as fait du C, c'est le même problème entre pointeur et valeur pointée. Je vais donc t'expliquer.

    En ASM (syntaxe Nasm), lorsque tu fais ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    section .data
    max db 255
    tu donne juste un masque (le label max) à une adresse mémoire non connue jusqu'à l'exécution de ton programme. Autrement dit, lorsque le programme sera chargé en mémoire et le système lui assignera une plage d'adresse, si max est placé, disons à l'adresse 0x1234, faire ceci:

    est équivalent à faire ceci :

    C'est commesi tu essai de mettre l'adresse de max dans EAX. Pour éviter cela, il faut déréférencer le pointeur en la valeur pointée. La syntaxe Adéquate (sous Nasm)pour faire cela est ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mov EAX, [max] ; le crochet dit je veux le contenu de l'adresse où se trouve max

    Maintenant, cela ne suffit pas. En effet, le label max commence à 0x1234. Mais où se termine-t-il ? Fait-il 2 octets ? un octet ? pour éviter cela on utilise ce que l'on appelle les spécificateur de taille. Donc pour avoir un code correcte, il faudra aussi préciser combien d'octets tu veux à partir de 0x1234 (notre cher max). Voilà comment procéder :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mov EAX, byte [max] ; nous voulons récupérer 1 byte (octet) à partir de l'adresse où se trouve max.

    Maintenant parlons de comparaison. En fait, tu as fais l'essentiel, utiliser cmp et une instruction de saut, il faut maintenant utiliser les bon spécificateurs de taille et les valeurs pointées et non les pointeurs. Si je reprends donc ton exemple en le corrigeant un peu, on aura :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mov BX, byte [max] ; je te conseillerais d'utiliser BX, vu que tu compare des octets, et tu ne sais pas ce qui dans la partie haute de BX 
               cmp AX, BX
              ja _plusgrand
    ou bien si je conserve les même registres que toi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    movsx EBX,  byte [max] ; je copie en remplissant les parties hautes avec les bonnes valeurs pour conserver le signe des valeurs
               cmp EAX, EBX
              ja _plusgrand

    J'espère que j'ai été clair et compréhensif.


    PS: voir ce lien Comment permettre à l'utilisateur d'entrez des choix et puis comparer ces choix dans une condition où j'ai répondu à une question similaire avec une code complet.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Novembre 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Novembre 2018
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Merci beaucoup pour l'explication. Cependant quand je fais :
    On me sort :
    Invalid size for operand 2
    Le même problème intervient quand j'utilise BX

  6. #6
    Membre du Club
    Homme Profil pro
    Ceo
    Inscrit en
    Décembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Ceo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 25
    Points : 44
    Points
    44
    Par défaut
    On me sort : Invalid size for operand 2
    Le meme problème intervient quand j'utilise BX
    C'est tout à fait normal. Regarde mes explications plus haut et tu comprendras. En fait EAX c'est 32 bits de taille et là tu essai de faire un mov entre deux opérandes de différentes tailles (max à un octet de taille et EAX à 4 octets de taille). C'est pour cela il faut utiliser movsx/movzx quand deux opérandes ont différentes tailles.

    Ou soit donc tu change les registres en des tailles plus petites et compatibles entres elles en utilisant l'instruction mov ou bien simplement tu change le mov en movsx là le nombre plus petit est étendu pour remplir le registre de taille plus grande tout en respectant son signe de base. Si tu ne comprends toujours pas, dit le et je vais réexpliquer avec plus de détails.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Novembre 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Novembre 2018
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    J'ai essayé avec movzx, il y'a en effet pas d'erreur mais le résultat n'est pas bon : le saut se fait dans les 2 sens ( Nombre plus grand et nombre plus petit)

    Avec movsx, pas d'erreur aussi, mais c'est le contraire, le saut ne se fait en aucun sens.

    Avec les registres à 8 bits le résultat est le meme pour movsx, le saut se fait en aucun sens

    J'apprécie beaucoup ton aide

  8. #8
    Membre du Club
    Homme Profil pro
    Ceo
    Inscrit en
    Décembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Ceo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 25
    Points : 44
    Points
    44
    Par défaut comparaison de valeur en assembleur, nombre signé vs nombre non-signé
    J'ai essayé avec movzx, il y'a en effet pas d'erreur mais le résultat n'est pas bon : le saut se fait dans les 2 sens ( Nombre plus grand et nombre plus petit)
    Encore une fois, c'est un comportement plus ou moins attendu. En effet, dans le monde des machines, il n'existe pas de nombres non-signés ou de nombres signés. Il n'y a que des bits !

    Ce que beaucoup ignorent donc c'est que les instructions de saut (ja jne je...) ne s'équivalent pas et se comportent différemment (teste des bits du flags différents) selon que le programmeur se considère devant un nombre signé ou non signé.

    Dans ton cas donc, ton code est syntaxiquement correct mais apparemment tu n'emploie pas la bonne instruction de saut. Poste ton code au complet et je vais approfondir les explications.

    PS: voyant que tu souhaite partir d'un niveau débutant pour comprendre, l'ASM, voici un excellent bouquin écrit par moi qui pourrais t'aider ( https://x86asmdemystified.landen.co/ )

  9. #9
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Novembre 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Novembre 2018
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Je sais qu'on peut utiliser d'autres instructions de saut comme JG et JL, j'ai essayé de changer mais ça ne marche toujours pas.

    Mon code est énorme je peux pas le poster ici, est-ce que ça te dérangerait si j'envoie le document par mail ?

  10. #10
    Membre du Club
    Homme Profil pro
    Ceo
    Inscrit en
    Décembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Ceo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 25
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par Neo Craft Voir le message
    Mon code est énorme je peux pas le poster ici, est-ce que ça te derangerait si j'envoie le document par mail ?
    Je veux juste avoir la partie qui traite du problem dont tu parles. C'est possible ? Sinon je t'enverrai mon email.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Novembre 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Novembre 2018
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par cotoporto Voir le message
    Je veux juste avoir la partie qui traite du problem dont tu parles. C'est possible ? Sinon je t'enverrai mon email.
    La voilà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    movsx eax, byte[nombre] ; Nombre étant l'input faite par l'utilisateur
               movsx ebx, byte[max]
               cmp eax, ebx
               ja _plusgrand
    J'ai déjà essayé avec JG mais le résultat n'est pas ce que recherche.

  12. #12
    Membre du Club
    Homme Profil pro
    Ceo
    Inscrit en
    Décembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Ceo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 25
    Points : 44
    Points
    44
    Par défaut
    Ok je vois. Alors voilà. Il y une explication possible :

    tu entre la limite maximale que peut contenir un byte avant de vouloir l’étendre

    Soit 255. Donc s'il y a 1111 1111 (255) dans l'entrée utilisateur, en faisant un movsx, le cpu croit que le signe de ton nombre est négatif (notation par complément oblige) alors il étend cela à 32 bits en faisant ceci 1111 1111 1111 1111 1111 1111 1111 1111 (-1). Voilà donc ce que ton code fait :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    movsx eax, byte[nombre] ; si nombre  255 EAX contient 0xFFFF Donc négatif 
    movsx ebx, byte[max] ; si max  255 EBX contient 0xFFFF sinon si  < 255 il sera considéré positif par l'instruction ja
    cmp eax, ebx ; implicitement c'est EAX - EBX 
    ja _plusgrand ; test les flags CF et ZF qui ne s'allument pas ici car en présence de nombres signés
    Comme les commentaires du code l'indiquent, si ton max à une valeur maximale à la limite que peut contenir son "type", alors l'extension de signe peut mal se passer. Alors lors de la comparaison, des résultats aberrants apparaîtront car ce n'est rien d'autre qu'une soustraction sans rétention du résultat. Et le flag CF ne sera pas allumé donc le saut ne n’effectuera pas.

    La même chose peut arriver au niveau de la variable max. Maintenant pour palier à cela, étend ton nombre max à plus d'un byte en mettant des 0 au début. Un truc comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    section .data
    max dw 0xFF    ; 0000 1111
    ou bien tu utilisera movzx qui étendra ton nombre dans les registres tout en s'assurant qu'ils sont positifs. Un truc comme ceci doit être fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    movzx EAX, byte [max] ;max est positif
    en faisant cela tu pourras ensuite effectuer tes comparaisons sans problèmes. Finalement tu auras un code comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ; les deux nombres sont considérés positifs
    movzx eax, byte[nombre] 
    movzx ebx, byte[max]
    cmp eax, ebx
    ja  _plusgrand ; test CF et ZF
    si par contre pour une raison ou une autre tu te retrouvais à vouloir inclure des nombres négatifs, voilà quelque chose de mieux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ; les deux nombres sont considérés signés
    movsx eax, byte[nombre] 
    movsx ebx, byte[max]
    cmp eax, ebx
    jg  _plusgrand ; saut si des deux nombres signés, celui d'EAX est le plus grand, test SF, OF, et ZF
    Voilà. J'espère que ça marchera maintenant.

  13. #13
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Novembre 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Novembre 2018
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Merci pour l'explication bien détaillée, je comprends ton idée. Ça marche !

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

Discussions similaires

  1. comparer les valeurs d'un même tableau
    Par DelphLaga dans le forum Langage
    Réponses: 11
    Dernier message: 19/07/2006, 14h32
  2. comment comparer les valeurs retournés par DBGrid
    Par Ice-tea dans le forum Bases de données
    Réponses: 2
    Dernier message: 08/06/2006, 14h42
  3. [VBA-E] Comparer les valeurs entre classeur
    Par Mut dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 26/03/2006, 12h32
  4. Réponses: 17
    Dernier message: 31/12/2005, 21h32
  5. comparer les valeurs d'un tableau
    Par nicerico dans le forum ASP
    Réponses: 4
    Dernier message: 19/08/2004, 11h20

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