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 :

[NASM] Afficher un nombre en binaire, erreur macro


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 15
    Points : 17
    Points
    17
    Par défaut [NASM] Afficher un nombre en binaire, erreur macro
    Bonjour,
    je programme en nasm. J'utilise une macro pour afficher un nombre en binaire mais il m'affiche "invalid combination of opcodes...". Merci d'avance.

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
     
     
     
    %macro afficher_message 2
    	mov eax,4
    	mov ebx,1
    	mov ecx,%1
    	mov edx,%2
    	int 80h
    %endmacro
     
     
    %macro ecrire_dans_variable 2
    	mov eax,3
    	mov ebx,0
    	mov ecx,%1
    	mov edx,%2
    	int 80h
    %endmacro
     
    %macro atoi 2
            mov esi, %1
            xor eax, eax
            xor edx, edx
        %%loop:
            mov dl, byte [esi]          ; on recupere le caractere du chiffre courrant dans edx
            cmp dl, 10                  ; si dl contient un retour chariot on a fini de traiter la chaine
            je %%finish
            lea eax, [eax * 4 + eax]    ; eax = eax * 5
            add eax, eax                ; eax = eax + eax, donc a l'arrivee on a multiplie eax par 10 avec ces deux lignes
            add esi, 1                  ; on incremente le pointeur sur la chaine pour passer au chiffre suivant
            and dl, 0x0F                ; c'est une astuce pour recuperer la valeur decimale du chiffre, ca s'explique par la representation binaire, on aurait pu faire un sub 48 a la place
            add eax, edx                ; on additionne la valeur du chiffre a eax (qui a ete multiplie par 10 avant remember ?)
            jmp %%loop                  ; et on boucle
        %%finish:
            mov [%2], eax
    %endmacro
     
    %macro itoa 3
            mov eax, [%1]               ; on recupere le nombre la ou il est stocke
            mov edi, %2                 ; on recupere l'adresse du buffer de destination
            mov ebx, 10                 ; diviseur = 10
            xor ecx, ecx
        %%first_loop:
            xor edx, edx
            div ebx                     ; on divise eax par 10, le quotient va dans eax, le reste va dans edx
            push dx                     ; on stocke le reste, sachant qu'en divisant par 10 a chaque fois on stocke les chiffres dans l'ordre inverse -> 3,2,1
            inc cl                      ; longueur (de la chaine) = longueur + 1
            test eax, eax               ; tant que eax != 0, c'est a dire tant que qu'il y a un quotient qu'on peut diviser et nous donner un reste
            jnz %%first_loop
            mov [%3], ecx               ; ecx contient la longueur de la chaine, on stocke la valeur pour pas la perdre
        %%second_loop:                  ; la seconde boucle permet de convertir decimal -> ascii en ajoutant 48, et de remettre les chiffre dans l'ordre attendu (grace aux pop)
            pop ax                      ; donc on recupere le dernier chiffre traite
            or al, 00110000b            ; on lui ajoute 48 (la encore c'est un peu astucieux)
            mov byte [edi], al          ; et on le stocke dans le buffer de destination, de gauche a droite donc dans l'ordre -> "123"
            inc edi
            loop %%second_loop          ; jusqu'a ce que ecx = 0, c'est a dire qu'on ait traite toute la chaine
            mov byte [edi], 0
    %endmacro
     
    %macro itob 1
    	mov cl,1
    	mov ax,%1
     
    	binaire:
    	cmp cl,16
    	jg fin
     
    	rcl ax
    	ja zero
     
    	un:
    	afficher_message 49,1
    	jmp compteur
     
    	zero:
    	afficher_message 48,1
     
    	compteur:
    	inc cl
    	jmp binaire
     
    	fin:
     
    %endmacro
     
     
     
     
    section .text
    	global _start
     
    	_start:
     
    	afficher_message msg,msgl
    	ecrire_dans_variable nb_str,10
    	atoi nb_str, nb_dec
     
     
    	itob nb_dec
     
    	end:
    	mov eax,1
    	mov ebx,0
    	int 80h
     
     
     
    section .data
    msg: dw "Saisissez un nombre:",10,13
    msgl: equ $ - msg
    msgprem: dw "est premier",10,13
    msgpreml: equ $- msgprem
    msgnprem: dw "n'est pas premier",10,13
    msgnpreml: equ $- msgnprem
     
    section .bss
    	nb_str: resw 1
    	nb_dec: resw 1
    	sum_str: resw 2
    	sum_dec:    resw 2
    	sum_len:    resw 1
    J'ai l'erreur à cet endroit là

  2. #2
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    ligne 63 tu fais un mov ax, %1, quelle est la taille de nb_dec ? j'ai rien dit, c'est censé être un word (déclaré tout à la fin), mea culpa

    bon en fait c'est l'instruction rcl ax, cl qui génère l'erreur, il te manquait un paramètre tout simplement

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 15
    Points : 17
    Points
    17
    Par défaut
    Pour ceux que ça intéresse, un programme qui affiche en binaire le nombre saisi:


    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
     
     
     
     
    %macro afficher_message 2
    	mov eax,4
    	mov ebx,1
    	mov ecx,%1
    	mov edx,%2
    	int 80h
    %endmacro
     
     
    %macro ecrire_dans_variable 2
    	mov eax,3
    	mov ebx,0
    	mov ecx,%1
    	mov edx,%2
    	int 80h
    %endmacro
     
    %macro atoi 2
            mov esi, %1
            xor eax, eax
            xor edx, edx
        %%loop:
            mov dl, byte [esi]          ; on recupere le caractere du chiffre courrant dans edx
            cmp dl, 10                  ; si dl contient un retour chariot on a fini de traiter la chaine
            je %%finish
            lea eax, [eax * 4 + eax]    ; eax = eax * 5
            add eax, eax                ; eax = eax + eax, donc a l'arrivee on a multiplie eax par 10 avec ces deux lignes
            add esi, 1                  ; on incremente le pointeur sur la chaine pour passer au chiffre suivant
            and dl, 0x0F                ; c'est une astuce pour recuperer la valeur decimale du chiffre, ca s'explique par la representation binaire, on aurait pu faire un sub 48 a la place
            add eax, edx                ; on additionne la valeur du chiffre a eax (qui a ete multiplie par 10 avant remember ?)
            jmp %%loop                  ; et on boucle
        %%finish:
            mov [%2], eax
    %endmacro
     
    %macro itoa 3
            mov eax, [%1]               ; on recupere le nombre la ou il est stocke
            mov edi, %2                 ; on recupere l'adresse du buffer de destination
            mov ebx, 10                 ; diviseur = 10
            xor ecx, ecx
        %%first_loop:
            xor edx, edx
            div ebx                     ; on divise eax par 10, le quotient va dans eax, le reste va dans edx
            push dx                     ; on stocke le reste, sachant qu'en divisant par 10 a chaque fois on stocke les chiffres dans l'ordre inverse -> 3,2,1
            inc cl                      ; longueur (de la chaine) = longueur + 1
            test eax, eax               ; tant que eax != 0, c'est a dire tant que qu'il y a un quotient qu'on peut diviser et nous donner un reste
            jnz %%first_loop
            mov [%3], ecx               ; ecx contient la longueur de la chaine, on stocke la valeur pour pas la perdre
        %%second_loop:                  ; la seconde boucle permet de convertir decimal -> ascii en ajoutant 48, et de remettre les chiffre dans l'ordre attendu (grace aux pop)
            pop ax                      ; donc on recupere le dernier chiffre traite
            or al, 00110000b            ; on lui ajoute 48 (la encore c'est un peu astucieux)
            mov byte [edi], al          ; et on le stocke dans le buffer de destination, de gauche a droite donc dans l'ordre -> "123"
            inc edi
            loop %%second_loop          ; jusqu'a ce que ecx = 0, c'est a dire qu'on ait traite toute la chaine
            mov byte [edi], 0
    %endmacro
     
    %macro itob 1
    	mov cx,1
    	mov ax,%1
     
    	binaire:
    	cmp cx,16
    	jg fin
     
    	rol ax,1
     
    	push ax
    	push cx
     
    	jnc zero
     
     
     
    	un:
    	afficher_message msgun,msgunl
    	jmp compteur
     
    	zero:
     
    	afficher_message msgzero,msgzerol
     
     
    	compteur:
    	pop cx
    	pop ax
    	inc cx
    	jmp binaire
     
    	fin:
    	nop
     
    %endmacro
     
     
     
     
    section .text
    	global _start
     
    	_start:
     
    	afficher_message msg,msgl
    	ecrire_dans_variable nb_str,10
    	atoi nb_str, nb_dec
     
     
    	itob [nb_dec]
     
     
     
    	end:
    	mov eax,1
    	mov ebx,0
    	int 80h
     
     
     
    section .data
    msg: dw "Saisissez un nombre:",10,13
    msgl: equ $ - msg
    msgun: dw "1"
    msgunl: equ $- msgun
    msgzero: dw "0"
    msgzerol: equ $- msgzero
     
    section .bss
    	nb_str: resw 1
    	nb_dec: resw 1
    	sum_str: resw 2
    	sum_dec:    resw 2
    	sum_len:    resw 1
    @BufferBob: j'ai réussi à trouver seul cette erreur mais merci quand même.

  4. #4
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par Conan Edogawa Voir le message
    Pour ceux que ça intéresse, un programme qui affiche en binaire le nombre saisi
    à appeler une macro dans une macro dans une macro etc. tu risques de te marcher sur les registres un moment donné, il va falloir envisager de faire des fonctions (réellement indépendantes), sinon tout le reste est vachement bien, commenté et tout

Discussions similaires

  1. [XL-2003] Macro pour mise en page, affichant le nombre total de pages du classeur entier
    Par BtjpsspgrW dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 29/10/2014, 09h38
  2. [Débutant][Math] Afficher un nombre sans exposant
    Par tanguy dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 24/09/2012, 13h58
  3. Réponses: 8
    Dernier message: 18/04/2011, 14h46
  4. afficher un nombre sous format binaire?
    Par sofiane44 dans le forum C++
    Réponses: 2
    Dernier message: 20/01/2006, 18h47
  5. [VB6] Converssion de nombre en binaire
    Par bencheikh dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 08/02/2003, 11h13

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