Problème de restitution d'une chaîne.

Résolu
Sawteeth Messages postés 3 Date d'inscription samedi 25 novembre 2006 Statut Membre Dernière intervention 28 novembre 2006 - 25 nov. 2006 à 20:15
rannik Messages postés 3 Date d'inscription mardi 7 février 2006 Statut Membre Dernière intervention 15 mars 2008 - 15 mars 2008 à 00:05
Bonsoir. Je viens de débuter l'assembleur et j'ai tenté de faire un petit programme qui lit une chaîne au clavier et l'affiche à l'écran. Le problème est que lors de la restitution de la chaîne entrée s'affiche des données qui visiblement, appartiennent à un autre programme.
Voici le code (j'utilise TASM, TLINK et EXE2BIN, pour assembler et compiler.)
   .model tiny
   .386   
   .stack 100h
   .data
   mess1   db    "Entrez la chaine et tapez entrée",10,13,'$'
   cha1    db    32 dup(?)
   .code
   start:
   mov    ax,@data
   mov    ds, ax
   mov    es, ax
   
   mov    dx, offset mess1
   mov    ah, 09h
   int    21h
   
   mov    dx, offset cha1
   mov    ah, 0Ch ;fonction qui initialise le buffer
   mov    al, 0Ah ;et lit la chaîne.
   int    21h
   
   mov    dx, offset cha1
   mov    ah, 09h
   int    21h
   
   mov    ax,04c00h                
   int    21h
   end    start
Je vous remercie d'avance.

10 réponses

cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
27 nov. 2006 à 08:46
Bonjour Sawteeth,

J'ai une petite idée concernant ton problème: Je pense que lors de l'affichage de ton buffer ce dernier est effectivement effectué - mais que l'affichage continue (en affichant tous les caractères qui se trouveront après ton buffer) jusqu'à ce que par hazard on rencontre la valeur 24h soit "$".

Essaie de mettre un "$" dans ton buffer lorsque tu auras terminé ta saisie.
Tu peux peut être détourner la sortie vers un fichier pour visualiser tous les caractères qui sont effectivement sortis pour vérifier si ton texte correspond bien au début.

A+
3
Sawteeth Messages postés 3 Date d'inscription samedi 25 novembre 2006 Statut Membre Dernière intervention 28 novembre 2006
27 nov. 2006 à 21:04
Je vous remercie, je vais tenter cette idée, (excusez moi encore, mais par contre, comment concatène-t-on un caractère ascii à la chaîne préexistante ?) 
@+
3
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
28 nov. 2006 à 08:44
Bonjour Sawteeth,

Je ne me souviens plus ce que fait exactement la fonction 0Ch de l'interruption DOS. Si cette dernière met les codes ascii des caractères saisis, tu n'as qu'à mettre le code 24h après ton dernier caractère saisi. Pour celà il te faut connaitre la longueur de ta chaine. Ensuite tu fais un

mov [offset cha1+bp+1],byte 24h   si bp contient le nombre de caractères


Tu seras peut être amené à adapter le syntaxe pour TASM.
3
Sawteeth Messages postés 3 Date d'inscription samedi 25 novembre 2006 Statut Membre Dernière intervention 28 novembre 2006
28 nov. 2006 à 21:13
Ahhh mais oui... quel imbécile.
Merci beaucoup en tout cas... cette histoire me prend la tête depuis un petit moment !
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Guilou34 Messages postés 142 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 29 janvier 2016 1
2 déc. 2006 à 01:35
La fonction  0C  vide le buffer et ensuite appele la fonction  définie par le contenu de AL.
 Ici  c'est donc la fonction 0Ah c'est à dire "Buffered standard input"
Cette fonction demande que premier octet contienne la taille   du buffer  en octets .
Ce sera aussi le maximum de charactères qui seront lus.
Au retour, le deuxieme octet contiendra le nombre de charactères réèllement lus.
Dans  le cas présent , le premier octet du buffer est indéterminé, c'est bien entendu la valeur qu'il contient qui sera utilisée par la fonction 0C pour le vider. Si par malheur elle dépasse 32, c'est le code qui sera remis à 0!

Après  " mov dx, offset cha1"  il faut quelque chose comme :
mov di,dx 
mov byte  ptr [di],30 ; 30=taille de chain -2

et au retour ;  après l'appel  de l'int21 fonction 0ch :

mov al,[di+1]  ; al =nombre d'octest lus
xor ah,ah
add di,ax
 mov byte ptr  [di+2],'$'  ; termine la chaîne par un $

Quelques  remarques:
le modèle tiny n'utilise  qu'un seul segment de 64 ko pour cs,ds,es et ss
il est inutile de les initialiser.
 En appelant tlink avec l'option /t ,  exe2bin est inutile, le .com est généré automatiquement
Un modèle tiny doit toujours réserver 256 octets pour le système, ici la directive (inutile) .stack  100h  joue par chance ce rôle ,  il faut mieux avoir  org 100h.
Bonne continuation
3
rannik Messages postés 3 Date d'inscription mardi 7 février 2006 Statut Membre Dernière intervention 15 mars 2008
7 mars 2008 à 01:33
Salut !

J'ai écrit un code dans ce style, car je débute aussi et j'en suis au même point. Sauf que mon code a un résultat étrange en fonction du nombre de caractère entrée. De plus je ne comprends pas pourquoi c'est impossible de donner à cx une référence plutot qu'une valeur (noob quand tu nous tiens ^^)

.386
fiche segment use16
assume cs:fiche, ds:fiche, ss:fiche
org 100h
debut:   mov ah, 0ch
            mov al, 0ah
            mov dx, offset nom
            int 21h

            mov di, 2d
            mov cx, 10d     
boucle:  mov ah, 02h
            mov dl, ds:[nom+di]   ; on pointe à priori sur le 3e octet (+1 a chaque tour)
            int 21h
            add di, 1d
            loop boucle
            ret

nom db 11, ?, 10 dup(?), ?
fiche ends
end debut

Tout est sympa quand on entre 10 caractère mais apres ...
0
Guilou34 Messages postés 142 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 29 janvier 2016 1
7 mars 2008 à 12:16
Salut
Pour être plus clair, à l'appel de l'int 21h, fonction 0ch,
dx doit pointer sur ce qu'on peut appeler une structure, quelque chose comme ceci :

mov dx offset nombre 
...
... 
avec:
nombre   db 11  ; Le  lecture du clavier se terminera après un Enter ou après 11 caractères
octets_lus db ?   ;  nombres  de caractères réellement lus ( ici entres 0 et 11)
message db  11 dup (?)  ; les caractères seront rangés ici

L'instruction "loop boucle" est équivalente à ceci:
 dec cx       ; cx=cx-1
 jnz boucle  ; saute à boucle si cx   >0

If faut donc que cx contienne la taille du message, comme ceci:
mov cl,octets_lus
xor ch,ch  ;  = mov ch,0
boucle:
...
Il y a quelques maladresses dans ton code, mais l'essentiel est bien sur qu'il fasse ce que tu lui demandes.  
 Amicalement                                                               
0
rannik Messages postés 3 Date d'inscription mardi 7 février 2006 Statut Membre Dernière intervention 15 mars 2008
14 mars 2008 à 04:12
Salut,

tout d'abord merci d'avoir répondu ...

Ces maladresses j'en suis très conscient : ) j'ai que 2 soirs de découverte du ASM à mon actif et j'ai un peu plus de temps pour m'y reconsacrer maintenant.

Apres avoir lut un vieux tuto sur l'architecture x86, le mode réel, le fonctionnement des registres et du DOS, je me suis simplement posé comme problème tout bête si facil en langage de haut niveau :

comment faire pour afficher une chaîne lue au clavier ? : ) Car de toute évidence découvrir ça en asm à bas niveau n'est pas simple (je connais que ruby et php).

J'ai donc cherché une documentation sur les interruptions du DOS, où je n'ai trouvé, bien évidement, aucun exemple exhaustif (en français) à me mettre sous la dent concernant le fonctionnement de 0ch.

j'ai finis par bidouiller ce code malin qui ne l'est pas ... ^^

Donc pour en revenir à nos moutons ... pourquoi déclarer de cette façon =>> message db  11 dup (?)
Je croyais qu'il fallait prévoir dans la déclaration d'une part le nombre d'octets attendu + 1 (le caractere de fin de ligne), ensuite un octet pour le nombre de caractère réellement lus, puis ensuite le tableau du nombre d'octet attendu + fin de ligne.
Ce qui donnerait précisement : nom db 11, ?, 10 dup(?), ?
J'ai trouvé un exemple de cette déclaration dans un ptit tuto sur un site et je me rends compte que ton explication n'a rien à voir avec ce que j'ai lu ... Je ne connais guère pour l'instant le format de la fonction 0ch, mais j'imaginais qu'elle stockait automatique le nombre d'octets lu sur le 2e octet du buffer, valeur que je voulais répérer pour la passer à cx.
0
Guilou34 Messages postés 142 Date d'inscription mercredi 5 avril 2006 Statut Membre Dernière intervention 29 janvier 2016 1
14 mars 2008 à 14:10
Salut
Ce qui t'a échappé c'est  qu'à l'appel de l'int 21 j'ai écrit:
"mov dx, offset nombre" et pas "mov dx,offset message" donc dx pointe bien sur une structure

Je trouve tes essais bien sympathiques mais je crois  qu'il te faut d'abord un bon tuto.  
 
0
rannik Messages postés 3 Date d'inscription mardi 7 février 2006 Statut Membre Dernière intervention 15 mars 2008
15 mars 2008 à 00:05
Ouep, je crois aussi, car certaines choses sont encore un peu sombres : )

Jvais me mettre à l'anglais : Art of Assembly Book

Car je n'ai trouvé aucun tuto en français digne de ce nom, soit ils répètent tous inlassablement la même chose en s'éternisant sur des notions qui n'en ont pas besoin, soit ils passent vite fait sur des détails qui mériteraient autre chose qu'une explication "télégrammique".

Merci à toi et je me rappelerais de tes explications.
0
Rejoignez-nous