Merci de ta réponse
Si si c'était le but. Je voulais vérifier que le scan enregistrait correctement ce que j'écrivais. L'affichage de ce que j'écris sert juste au retour visuel, le print à afficher la chaine de caractère string: en entier
Merci de ta réponse
Si si c'était le but. Je voulais vérifier que le scan enregistrait correctement ce que j'écrivais. L'affichage de ce que j'écris sert juste au retour visuel, le print à afficher la chaine de caractère string: en entier
Visiblement c'est plutôt un problème d'attribut d'affichage qui cloche.
En fait ton caractère est bien écrit, mais en noir sur fond noir
Avant d'appeler l'int 10h, BH doit contenir le numéro de la page, mais BL doit contenir le numéro de couleur.
et avec un XOR BX,BX, bien ta couleur elle vaut 0 (la couleur par défaut vaut 7)
edit : petit lien vers un site bien sympa : http://www.gladir.com/LEXIQUE/INTR/INT10.HTM
Merci de ta réponse. La question est pourquoi quand j'apelle le print sans passer par le scan ma variable s'affiche correctement (valeur de basse "hello") ?
je ne comprends pas ce que tu ne comprends pas
ta fonction SCAN stocke tes caractère à la position de [SI]
et comme tu lui indiques que SI=adresse de string, la saisie vient écraser le hello...
ça je sais x), on s'est mal compris
Enft ce que j'essaie d'expliquer c'est que quand OS.asm il y a :un magnifique hello de toute beauté s'affiche à l'écran.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 org 0x0100 OS: mov si, string call print ;jmp OS ret ;Variables string: db "Hello", 0 ;Inclusions %include "FUNC-IO.asm"
Quand OS.asm contient :au niveau du scan je change le contenu de ma variable string (c'est le but xD) en général par test, comme sur l'image donné il y a quelque post. Puis au moment du print le premier caractère ne s'affiche pas correctement. Alors qu'avec le prmier exemple (qui utilise la même fonction print) le H de Hello s'affiche tout comme il faut. J'ai essayé de sauter le retour à la ligne (STOPSCAN) et j'ai modifié le code pour bien mettre le 0 à la fin de la varriable; et la comme on si attend j’obtiens "testtest" avc le premier résultant du scan et le deuxième du print
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 org 0x0100 OS: mov si, string call scan mov si, string call print ;jmp OS ret ;Variables string: db "Hello", 0 ;Inclusions %include "FUNC-IO.asm"
Sauf que je ne comprends pas le problème crée par ma fonction de retour à la ligne et son influence sur le print qui suit.
J'ai essayé de faire au plus claire Je remets FUNC-IO.asm ici pour plus de facilité
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 ;------------------------------------------------------------------------AFFICHAGE CHA�NE DE CARATERE--------------------------------------------------------------------------- print: mov ah, 0Eh ;Code d'instruction �criture d'un caract�re xor bx, bx ;RAZ (param�tres inutiles) print1: mov al, [si] ;Déplace caractère à afficher dans AL or al, al ;Test de fin de variable (si AL = 0) jz STOP ;Si AL = 0 nouvelle ligne int 10h ;INT gestion affichage inc si ;Caractère suivant jmp print ;Boucle affichage ;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ;-------------------------------------------------------------------------GESTION CLAVIER----------------------------------------------------------------------------------------------------- scan: mov ah, 01h ;Teste buffer clavier scan1: int 16h ;INT gestion clavier jz scan1 ;Boucle si aucune touche pr�s�e xor ax, ax ;RAZ du code d'instruction int 16h ;INT gestion clavier cmp al, 13 ;Test retour chariot je STOPSCAN ;Fin de la fonction si retour chariot mov [si], al ;Met le caract�re �crit dans si mov ah, 0Eh ;Code d'instruction �criture d'un caract�re int 10h ;INT gestion affichage inc si ;Passe à l'octet suivant de la variable jmp scan ;Boucle STOPSCAN: ;Sortie de fonction mov ah, 03h ; int 10h ; inc dh ;Nouvelle ligne xor dl, dl ; mov ah, 02h ; int 10h ; mov [si], dl ;Fin de variable 0 à la fin dl = 0 ret ;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ STOP: ret
comme je te l'avais écrit, plus haut, la fonction de l'interruption 10h attend les attributs vidéo (couleurs) dans le registre BL
ce qui m'étonne à moi, ce n'est pas qu'il manque la première lettre, mais que les autres s'affichent
place un "mov bl,7" avant d'appeler l'interruption 10h, j'imagine que ça résoudra ton problème
Et bien non x)
Au final j'ai mis le mov bl, 7 après le xor mais j'ai exactement le même problème xD
PS : j'ai mis mov bl, 07 pas mov bl, 7 mais ça change rien... si ?
mmmhhh... intrigué je suis alors...
ça me donne envie de faire des tests
tu utilises quoi comme compilo ?
Bonjour.
Ce bug est vraiment mystérieux ...
Personnellement, j'aurais commencé par utiliser un debugger afin de regarder ce qu'il y a en mémoire après la saisie du texte.
Cela permet se savoir si le problème se situe au niveau de la saisie ou bien au niveau de l'affichage.
En l'absence d'un debugger, la démarche naturelle pour dépister une erreur consiste à supprimer le superflu et se limiter à l'essentiel.
Et bien, supprimez ce saut de ligne !Le problème semble se situer au niveau du saut de ligne (STOPSCAN)
J'utilise Nasm pour Dos
@Prof En supprimant le saut de ligne mon 2ème test s'affiche correctement aris
Je sais que j'ai besoin d'un debuger mais en cherchant "debuger nasm" sur Google (qui est pourtant mon ami) je ne trouve rien. Je suis ouvert à toute solution x)
PS: Mon code s'execute sur Dosbox
Bien.@Prof En supprimant le saut de ligne mon 2ème test s'affiche correctement
Maintenant on sait que le problème se situe dans ce saut de ligne.
Il faudrait le couper en morceaux et tester chacun des morceaux.
J'ai trouvé une solution alternative :
Ça donne un retour à la ligne tout comme il faut mais je tiens quand même à connaître la raison de l'échec de ma solution que je me suis trouvé moi-même x)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 STOPSCAN: mov al, 10 mov ah, 0Eh int 10e mov al, 13 int 10h xor dl, dl mov [si], dl ret
Le dernier code montré me parait bizarre : qu'est-ce que ce "int 10e" à la ligne 5 ?
Un "int 10h" mal recopié ?
Sinon, utiliser la fonction 0Eh de l'interruption 10h pour aller à la ligne est une bonne idée.
Surtout que cela semble fonctionner, alors que la manipulation directe du curseur présente un bug.
Pour trouver précisément ce bug, il faudrait procéder par étape, comme je l'ai dit dans mon post précédent :
Première étape, demander uniquement la position du curseur sans modifier cette position.
Puis modifier la position du curseur en ajoutant 5 (par exemple) à la colonne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 STOPSCAN: ;Sortie de la fonction scan xor al, al ;al = 0 mov [si], al ;terminer la chaine par un 0 mov ah, 03h ;demander la position du curseur xor bh, bh ;page écran n° 0 int 10h ret
Puis aller à la ligne suivante sans modifier la colonne.
etc ...
Indépendamment du problème du curseur, le code contient une erreur qu'il faut impérativement corriger.
Cela concerne la taille du buffer d'entrée.
La chaine entrée au clavier est placée à l'adresse string.
Elle remplace donc la chaine "Hello".
Si la chaine entrée fait plus de 5 lettres, les lettres en plus et le 0 final vont écraser le code qui suit, c'est-à-dire le code de la procédure print.
Bonjour les dégâts !
Il faut donc prévoir un buffer assez grand pour recevoir une ligne de caractères, surtout si ce code doit resservir plus tard dans un autre projet.
Une taille de 128 octets me parait bien pour un début.
Donc remplacer
par
Code : Sélectionner tout - Visualiser dans une fenêtre à part string: db "Hello", 0
Code : Sélectionner tout - Visualiser dans une fenêtre à part string: db 128 dup(0), 0
Oui j'ai mal recopié x) Ya que mon téléphone qui peut aller sur internet en Finlande (je sais pas pourquoi d'ailleurs) du coup j'ai la correction automatique.
Je ferais les test tranquillement à la maison là je suis sous un vieux xp je préfère avancer.
J'étais au courant pour la taille de la variable je cherchais juste une solution pour empêcher de dépasser lors de l'écriture...
Sinon tu connais un debuger pour nasm ? (je me permets de te tutoyer si ça ne te dérange pas )
Désolé, mais j'utilise TASM et le debugger qui est livré avec.
Je ne connais pas NASM et je ne sais pas s'il y a un outil spécifique pour lui.
Peut-être faudrait-il voir du coté des debuggers génériques, sachant qu'ici il faut traiter du code 16 bits, ce qui n'est plus à la mode ...
Hello !
bon, j'ai insallé nasm pour dos et lancé ton programme dans dosbox
verdict : j'ai le même problème de première lettre non affichée.
Par contre ce problème n'arrive QUE quand je suis en bas de l'écran.
Si je fais un CLS avant de lancer le programme, ça fonctionne
Le problème est visiblement lié à la fonction 2 de l'int 10h (positionnement du curseur) quand ce dernier dépasse la hauteur de l'écran
En gros, le positionnement n'est pas correct, la lettre qui doit s'afficher en premier ne l'est pas, mais permet un repositionnement
du curseur au bon endroit après un scroll vertical
pour éviter ce problème, le plus simple, et de laisser la fonction d'affichage gérer le saut à la ligne
et donc de remplacer
Par ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 STOPSCAN: ;Sortie de fonction mov ah, 03h ; int 10h ; inc dh ;Nouvelle ligne xor dl, dl ; mov ah, 02h ; int 10h ; xor dl, dl ; mov [si], dl ;Fin de variable 0 à la fin dl = 0 ret
pour ce qui est de limiter le nombre de lettres, il faut simplement utiliser un compteur
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 STOPSCAN: ;Sortie de fonction mov ax, 0E0Dh ; retour chariot (CR) int 10h ; mov ax, 0E0Ah ; ligne suivante (LF) int 10h ; xor dl, dl ; mov [si], dl ;Fin de variable 0 à la fin dl = 0 ret
quand ce dernier arrive à la valeur maxi, tu jumpe à stopscan comme pour la touche enter
tu peux aussi gérer certaines touches comme Back-Space, histoire de permettre la modification de la ligne tapée
Merci pour toutes ces infos
J'ai adapté le code pour utiliser backspace en fin de variable avécu l'affichage qui va bien du coup ce que je vois à l'écran est exactement ce que j'obtiens dans ma variable. C'est parfait
Cependant pour ce qui est du dépassement de variable une idée m'est venu (et elle marche parfaitement après test).
Au lieu de connaître la longueur de la variable dans une autre variable, je connais l'adresse de fin (-1 pour le 0 de fin). Ce qui permet d'économiser une variable (certes temporaire) ainsi que du temps d'exécution (pas d'incrémentation).
Cependant si je m'amuse à faire de la copie de chaîne de caractères (par exemple) je vais avoir besoin de cette information. Avec une simple soustraction je peux l'obtenir, mais la question est, d'expérience et surtout au niveau os, est-c'est plus optimisé ?
J'essayerai de faire un edit avec le code (je n'y ai pas accès sur mon téléphone et mon pc a pas internet) pour plus de simplicité
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager