Affichage d'une variable en assembleur

Résolu
Bonjour, je suis un débutant en assembleur, je programme avec le TASM 5.0

Je voudrais bien savoir comment afficher une variable entière ..
j'ai essayé avec la fonction 09h, mais ceci n'a pas marché, rien est affiché lors de l'exécution ..
Merci d'avance

10 réponses

  1. Hé bien ton programme doit sans doute fonctionner, mais à mon sens il souffre d'un défault de conception, dans le fait de 'compter le nombre de fois que AH contient 10' plutôt que diviser par 10 pour le calculer directement...
    J'ai l'impression que la division te rebutes un peu ! c'est normal, à mes débuts je la trouvais également un peu compliquée !
    Mais dans ce cas précis, elle remplaçerait avantageusement la boucle tout en étant beaucoup plus rapide...
    Sinon, et puisque tu as l'air de te contenter de 2 chiffres, tu peux aussi employer une instruction moins courante, nommée 'AAM';
    Cette instruction divise le contenu de AL par 10 en mettant le chiffre de poids fort dans AH et le faible dans AL :
      Mov  AL, a
      Add  AL, b
      AAM           ; AH contient la dizaine et AL le reste
      Add  AX,3030h ; Ajoute 48 (30h) sur les 2 en même temps
      mov chaine[0], al
      mov chaine[1], ah
    
    1. Erreur de ma part, il faut inverser AL et AH :
        mov chaine[0], AH
        mov chaine[1], AL
    2. Merci infiniment ! j'ai beaucoup appris sur ce sujet, merci encore et bon courage :)
    3. Plaisir partagé ! Bonne continuation...
  2. voivi ce que j'ai pu faire, et ça a marché lors de l'execution
    data segment 
    
    a db 15 
    b db 16 
    chaine  db 3 dup ('$') 
    
    data ends 
    
    code segment 
    
    assume cs: code, ds: data 
    
    begin: 
    
    mov ax, data 
    mov ds, ax 
    
    mov ah, a 
    add ah, b 
    
    mov al, 0 
    
    boucle: 
    sub ah, 10 
    inc al 
    cmp ah, 10 
    jl suite 
    jmp boucle 
    
    suite: 
    add al, 48 
    add ah, 48 
    mov chaine[0], al 
    mov chaine[1], ah 
    
    mov dx, offset chaine 
    mov ah, 09h 
    int 21h 
    
    mov ah, 4ch 
    int 21h 
    
    code ends 
    end begin


    Pourrais tu me donner ton avis ?
    To really understand what's Death, we should live it
    par ce que c'est pas tous les jours qu'on a le droit à un nouveau départ
    1. Bon, just une question, on m'a parlé d'une fonction qui marche avec l'int 21h, c'est la fonction 02h qui affiche la valeur d'une variable en ASCII, i.e sans conversion ... j'ai pas su l'utiliser, est ce qu'elle existe vraiment? si c'est le cas, ce n'est pas la peine d'utiliser un tableau, j'ai pensé à faire la procedure suivante:

      mov si, 0
      boucle:
      sub ax, 10
      inc si
      cmp ax, 10
      jl suite
      jmp boucle

      suite:
      .
      .
      .


      et ensuite, il s'agit d'afficher les deux : ax, qui contient le reste de la division sur 10; et si, le quotient !
      1. Oui, la fonction 02h existe bien, mais elle ne permet d'afficher qu'un seul caractère, statut quo donc...
    2. Ha oui, la syntaxe des commentaires c'est une erreur de ma part, c'est aussi une syntaxe delphi en fait, l'habitude tenace est revenue au galop !

      Quand au fonctionnement avec SI, il faut comprendre que toute portion mémoire est accédée en fonction de son adresse, donc quand tu écris
      'Mov Tab[0], dx' il sera transformé en 'Mov [adresse de Tab[0]], DX'...
      Donc si tu charge l'adresse dans un registre, SI en l'occurence, tu peux accéder à Tab de la même manière avec 'Mov [SI],DX'.
      Dans l'instruction 'Mov SI, Offset Tab[05]' on charge l'adresse du dernier emplacement du tableau 'Tab' dans 'SI';
      Ensuite on place le caractère de fin de chaine avec 'Mov byte ptr [SI] ,'$'' puis, en décrémentant, les caractères constituants le nombre.
      Cette opération se fait dans le sens inverse car le reste de la division donne le caractère le plus faible, ça évite donc de devoir les inverser ensuite...

      Puis pour l'affichage on met la valeur de 'SI' dans DX, c'est à dire l'offset du début de la chaine. ça revient au même que 'Mov DX, offset Tab[0] ' à ceci près qu'on ne sais pas combien il y a de caractères pour représenter le nombre, donc on utilise 'SI' car il pointe sur le dernier caractère sorti, donc le 1er caractère à afficher...
      L'int21-09h attend bien l'adresse de la chaine dans 'DX', et non une valeur à afficher.

      Tab fait 6 octets car en 16 bits on aura au maximum 5 caractères (65535 max) plus le caractère terminal '$'.
      Ultime précision, avant toute division il faut mettre 'DX' à zéro, car il est censé être le reste d'une potentielle division précédente, et si sa valeur dépasse celle du diviseur, le processeur génèrera une erreur au même titre qu'une division par zéro.

      Le chêne aussi était un gland, avant d'être un chêne
      1. Merci pour cette réponse, mais est ce que tu peux m'expliquer quelques trucs ...

        PS : j'ai remarqué que dans ton programme, tu utilise la syntaxe du C pour les commentaire =p

        voilà le code
        data segment
        a dw 11h
        b dw 18h
        c dw ?
        tab db 06 dup (?)

        data ends

        code segment

        assume cs : code, ds : data

        begin:

        mov ax,data
        mov ds, ax

        mov AX, a
        add AX, b ; je préfère AX ici car il est le divisé
        mov c, AX ; et DX sert aussi dans la division

        Mov SI,offset tab[05]
        Mov Byte ptr [SI],'$'
        Mov CX,10;
        ;********************************************************
        ;en fait,ça fait quoi au just, est ce que ça a une relation avec tab que j'ai ;déclaré, et qui n'est pas utilisé (à directement à mon petit savoir)
        ;********************************************************
        @Bcl:
        Dec SI ; On commence par décrémenter car on a déjà mis '$'
        Xor DX,DX ; Xor plutôt que 'Mov DX,0' car plus compact
        Div CX ; Divise AX par 10, DX contient le reste
        Add DL,48 ; Ajoute '0' en ascii
        Mov [SI],DL ;Ajoute le caractère
        And AX,AX ; Teste si AX vaut 0
        Jnz @Bcl

        ; En sortie de boucle, SI pointe sur le 1er caractère du nombre

        Mov DX,SI
        Mov AH,09h
        Int 21
        ;*********************************************************
        ;est ce que c'est vraiment le tableau qui va étre affiché là? oubien SI ???
        ;********************************************************

        ; interruption du programme DOS
        mov ah, 4ch
        int 21

        code ends
        end begin
        1. Pas la peine de t'excuser : je te renvoie à ma devise !
          Alors voici l'idée générale, avec divisions multiples pour extraire les caractères en base 10. Je ne sais pas si ça va fonctionner directement dans ton assembleur et je ne peux pas tester, alors il y aura peut-être quelques corrections à apporter...
          Hésite pas si tu as des questions !
          data segment     
            a dw 11h     
            b dw 18h     
            c dw ?     
            tab db 06 dup (?)     
          
          data ends     
          code segment     
          assume cs : code, ds : data     
          
          begin:     
          
            mov   ax,data     
            mov   ds, ax     
          
            mov   AX, a     
            add   AX, b  ; je préfère AX ici car il est le divisé     
            mov   c, AX  ; et DX sert aussi dans la division     
          
            Mov   SI,offset tab[05]     
            Mov   Byte ptr [SI],'$'     
            Mov   CX,10;     
          
          @Bcl:     
            Dec   SI   // On commence par décrémenter car on a déjà mis '$' 
            Xor   DX,DX    // Xor plutôt que 'Mov DX,0' car plus compact     
            Div   CX       // Divise AX par 10, DX contient le reste     
            Add   DL,48    // Ajoute '0' en ascii     
            Mov   [SI],DL  // Ajoute le caractère     
            And   AX,AX    // Teste si AX vaut 0     
            Jnz   @Bcl    
          
            // En sortie de boucle, SI pointe sur le 1er caractère du nombre     
          
            Mov   DX,SI     
            Mov   AH,09h     
            Int   21     
          
            ; interruption du programme DOS     
            mov   ah, 4ch     
            int   21     
          
          code ends     
          end begin

          Le chêne aussi était un gland, avant d'être un chêne
          1. exusez moi, mais je suis super nul pour l assembleur, voici mon code source :

            ; segment des variable et données
            data segment

            a dw 11h
            b dw 18h
            c dw ?
            tab dw 2 dup (?)

            data ends

            code segment

            assume cs : code, ds : data

            begin:

            mov ax,data
            mov ds, ax

            ; additioner A et B, le mettre dans le AX, ensuite le transmettre dans C
            mov dx, a
            add dx, b
            mov c, dx

            ; affichage du résultat stocké dans la variable C
            mov si,0

            boucle1:
            sub dx, 10
            INC si
            cmp dx, 10
            JL suite
            JMP boucle1

            suite:
            mov tab[1], si
            mov tab[0], dx

            mov dx, offset tab[0]
            mov ah, 09h
            int 21

            mov dx, offset tab[1]
            mov ah, 09h
            int 21

            ; interruption du programme DOS
            mov ah, 4ch
            int 21

            code ends
            end begin
            1. Ha oui bien sûr, les fonctions dos n'affiche que des chaines de caractères ! Donc il faut que tu réserve une chaine et que tu la remplisse...
              Pour ce faire, il te suffit de diviser successivement la valeur par 10, puis d'ajouter 48, le code ascii pour '0', au reste de la division contenu dans EDX. Tu obtiendras ainsi les caractères de droite à gauche...
              1. Wé, apparement, ce n'e'st point un problème de code, mais de conversion
                On m'a dit qu'il faut convertir le nombre de l Héxa en ASCII ..??
                1. Peux-tu mettre ton code, pour être sûr que tout est bien paramétré ?