Affichage d'une variable en assembleur
Résolu
chiti_
Messages postés
1046
Date d'inscription
Statut
Membre
Dernière intervention
-
nicocorico Messages postés 799 Date d'inscription Statut Membre Dernière intervention -
nicocorico Messages postés 799 Date d'inscription Statut Membre Dernière intervention -
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
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
A voir également:
- Affichage d'une variable en assembleur
- Affichage double ecran - Guide
- Windows 11 affichage classique - Guide
- Problème affichage fenêtre windows 10 - Guide
- Problème affichage page internet google chrome ✓ - Forum Google Chrome
- Problème d'affichage/bugs graphiques sur Chrome sur Android - Forum Téléphones & tablettes Android
10 réponses
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 ..??
On m'a dit qu'il faut convertir le nombre de l Héxa en ASCII ..??
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...
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...
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
; 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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
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 !
Le chêne aussi était un gland, avant d'être un chêne
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
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
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
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
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
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 !
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 !
voivi ce que j'ai pu faire, et ça a marché lors de l'execution
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
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
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 :
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