Affichage d'une variable en assembleur
Résolu/Fermé
chiti_
Messages postés
1046
Date d'inscription
jeudi 16 août 2007
Statut
Membre
Dernière intervention
23 novembre 2014
-
25 nov. 2011 à 20:56
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 - 14 déc. 2011 à 04:57
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 - 14 déc. 2011 à 04:57
A voir également:
- Affichage d'une variable en assembleur
- Affichage double ecran - Guide
- Windows 11 affichage classique - Guide
- Comment agrandir l'affichage de l'écran - Guide
- Problème affichage fenêtre windows 10 - Guide
10 réponses
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
25 nov. 2011 à 21:44
25 nov. 2011 à 21:44
Peux-tu mettre ton code, pour être sûr que tout est bien paramétré ?
chiti_
Messages postés
1046
Date d'inscription
jeudi 16 août 2007
Statut
Membre
Dernière intervention
23 novembre 2014
128
28 nov. 2011 à 16:37
28 nov. 2011 à 16:37
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 ..??
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
28 nov. 2011 à 17:14
28 nov. 2011 à 17:14
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...
chiti_
Messages postés
1046
Date d'inscription
jeudi 16 août 2007
Statut
Membre
Dernière intervention
23 novembre 2014
128
1 déc. 2011 à 13:44
1 déc. 2011 à 13:44
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
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 1/12/2011 à 18:04
Modifié par nicocorico le 1/12/2011 à 18:04
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
chiti_
Messages postés
1046
Date d'inscription
jeudi 16 août 2007
Statut
Membre
Dernière intervention
23 novembre 2014
128
1 déc. 2011 à 20:49
1 déc. 2011 à 20:49
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
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 2/12/2011 à 05:27
Modifié par nicocorico le 2/12/2011 à 05:27
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
chiti_
Messages postés
1046
Date d'inscription
jeudi 16 août 2007
Statut
Membre
Dernière intervention
23 novembre 2014
128
2 déc. 2011 à 17:16
2 déc. 2011 à 17:16
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 !
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
3 déc. 2011 à 06:09
3 déc. 2011 à 06:09
Oui, la fonction 02h existe bien, mais elle ne permet d'afficher qu'un seul caractère, statut quo donc...
chiti_
Messages postés
1046
Date d'inscription
jeudi 16 août 2007
Statut
Membre
Dernière intervention
23 novembre 2014
128
Modifié par chiti_ le 2/12/2011 à 18:03
Modifié par chiti_ le 2/12/2011 à 18:03
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
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
3 déc. 2011 à 06:47
3 déc. 2011 à 06:47
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
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
3 déc. 2011 à 06:56
3 déc. 2011 à 06:56
Erreur de ma part, il faut inverser AL et AH :
mov chaine[0], AH mov chaine[1], AL
chiti_
Messages postés
1046
Date d'inscription
jeudi 16 août 2007
Statut
Membre
Dernière intervention
23 novembre 2014
128
13 déc. 2011 à 23:38
13 déc. 2011 à 23:38
Merci infiniment ! j'ai beaucoup appris sur ce sujet, merci encore et bon courage :)
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
14 déc. 2011 à 04:57
14 déc. 2011 à 04:57
Plaisir partagé ! Bonne continuation...