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. Peux-tu mettre ton code, pour être sûr que tout est bien paramétré ?
    0
    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 ..??
      0
      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...
        0
        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
          0
          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
            0
            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
              0
              1. 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
                0
                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 !
                  0
                  1. Oui, la fonction 02h existe bien, mais elle ne permet d'afficher qu'un seul caractère, statut quo donc...
                    0
                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
                  0
                  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
                    
                    0
                    1. Erreur de ma part, il faut inverser AL et AH :
                        mov chaine[0], AH
                        mov chaine[1], AL
                      0
                    2. Merci infiniment ! j'ai beaucoup appris sur ce sujet, merci encore et bon courage :)
                      0
                    3. Plaisir partagé ! Bonne continuation...
                      0