copie de chaines de caractères

copie de chaines de caractères - ASM - Programmation

Marsh Posté le 13-01-2003 à 17:38:36    

Voilà la manoeuvre: on saisit une chaine de caractère puis on l'affiche ensuite.
 
Buffer  DB 11
Taille  DB ?
ChainCar DB 11 DUP(?),'$'
 
Comment faire pour transférer le contenu du buffer dans la ChaineCar pour l'afficher?


Message édité par thenutskiller le 14-01-2003 à 12:03:05
Reply

Marsh Posté le 13-01-2003 à 17:38:36   

Reply

Marsh Posté le 14-01-2003 à 12:02:18    

Voilà le programme:
 

Citation :


        MOV CX,10
        MOV SI,0
 
        MOV AH,10
        LEA DX, Buffer          ; saisie dans le buffer
        INT 21H
 
 mov ah, 09h
 lea dx, newline  ; nouvelle ligne
 int 21h
 
 
    Boucle:
        MOV BL, Buffer[SI]      ; transfert du buffer
        MOV ChainCar[SI], BL    ; dans ChainCar
        INC SI
        CMP SI,CX
        JBE Boucle
         
 
        MOV AH, 9
        LEA DX, ChainCar        ; affichage de ChainCar
        INT 21H


 
Mais ça ne marche pas... si vous avez une idée

Reply

Marsh Posté le 14-01-2003 à 13:45:11    

Essaie de remplacer les lignes suivantes :
 
LEA DX, Buffer
LEA DX, ChainCar

 
Par :
 
MOV DX, offset Buffer
MOV DX, offset ChainCar


Message édité par Harkonnen le 14-01-2003 à 13:46:00

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 13:51:15    

REP MOVSB dest, source
 
c plus efficace qu'une boucle :o

Reply

Marsh Posté le 14-01-2003 à 13:51:16    

J'oubliais !
 
Essaie aussi de mettre  
 
MOV AH,10h
MOV AH,9h

 
Au lieu de  
 
MOV AH,10
MOV AH,9


Message édité par Harkonnen le 14-01-2003 à 13:51:41

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 13:53:02    

drasche a écrit :

REP MOVSB dest, source
 
c plus efficace qu'une boucle :o


[:tapai] pour le :o
 
sinon, c sur que le movsb est plus efficace, mais vu qu'il débute, je pense qu'il vaut mieux d'abord qu'il fasse selon sa méthode. l'optimisation viendra ensuite [:spamafote]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 13:53:50    

ça ne donne rien... il m'affiche des caractères bizarres...

Reply

Marsh Posté le 14-01-2003 à 13:56:12    

je n'ai plus les paramètres des fonctions 9h et 10h en tête, mais as tu vérifié si des registres sont utilisés par ces fonctions ?
dans ce cas, il serait bien de les empiler, puis de les vider au cas ou


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 13:56:45    

si je change le 10 par 10h, le programme ne demande même plus d'entrer qque chose et affiche des caractères étranges...

Reply

Marsh Posté le 14-01-2003 à 14:01:19    

crotte j'ai pas mon code source ici pour le REP MOVSB :(
 

  • bon en gros, tu remplis CX avec le nombre d'occurences;
  • tu dois positionner le flag de direction pour indiquer si tu vas copier du premier au dernier caractère (si je me rappelle bien: ce sera 0 si on va du début à la fin, et 1 si on va de la fin au début);
  • SI est rempli avec l'adresse de source (le début si tu comptes faire l'opération en incrémental, la fin si tu le fais en décrémental)
  • DI est rempli avec l'adresse de destination (cfr SI).


Enfin tu fais un REP MOVSB.  Le REP est là pour répéter la ligne autant de fois qu'il y a d'occurences indiquées dans CX.
A chaque fois que la ligne est exécutée:

  • SI et DI sont mis à jour pour travailler la prochaine occurence
  • CX va être décrémenté
  • Si CX vaut zéro, alors l'opération est terminée, et la ligne suivante sera exécutée.


Tout ceci de mémoire, j'ai un code qui fait ça et faudrait que j'aille vérifier dedans si j'ai pas dit une bourde.
Ca marche aussi avec d'autres instructions comme STOSB.
 
Harko: je :o si je veux quand même. (je vote le dernier jour :o)
Bon on va pas pourrir le topic pour ça hein!

Reply

Marsh Posté le 14-01-2003 à 14:01:19   

Reply

Marsh Posté le 14-01-2003 à 14:02:17    

thenutskiller a écrit :

si je change le 10 par 10h, le programme ne demande même plus d'entrer qque chose et affiche des caractères étranges...


10 = 10 alors que 10H = 16.

Reply

Marsh Posté le 14-01-2003 à 14:03:10    

Si je fais:
MOV AH,10
LEA DX,Buffer
INT 21H
 
MOV AH,9
LEA DX,ChainCar
INT 21H

avec ChainCar DB "Bonjour","$"
le message est affiché correctement, par contre, lorsque j'utilise un buffer que je transfert ensuite dans ChainCar, le programme affiche n'importe quoi (je suis presque sûr que c'est le transfert de Buffer à ChainCar qui est faux)...

Reply

Marsh Posté le 14-01-2003 à 14:04:14    

drasche a écrit :

crotte j'ai pas mon code source ici pour le REP MOVSB :(
 

  • bon en gros, tu remplis CX avec le nombre d'occurences;
  • tu dois positionner le flag de direction pour indiquer si tu vas copier du premier au dernier caractère (si je me rappelle bien: ce sera 0 si on va du début à la fin, et 1 si on va de la fin au début);
  • SI est rempli avec l'adresse de source (le début si tu comptes faire l'opération en incrémental, la fin si tu le fais en décrémental)
  • DI est rempli avec l'adresse de destination (cfr SI).


Enfin tu fais un REP MOVSB.  Le REP est là pour répéter la ligne autant de fois qu'il y a d'occurences indiquées dans CX.
A chaque fois que la ligne est exécutée:

  • SI et DI sont mis à jour pour travailler la prochaine occurence
  • CX va être décrémenté
  • Si CX vaut zéro, alors l'opération est terminée, et la ligne suivante sera exécutée.


Tout ceci de mémoire, j'ai un code qui fait ça et faudrait que j'aille vérifier dedans si j'ai pas dit une bourde.
Ca marche aussi avec d'autres instructions comme STOSB.
 
Harko: je :o si je veux quand même. (je vote le dernier jour :o)
Bon on va pas pourrir le topic pour ça hein!


 
Cette fonction (MOVSB) n'est pas dispo avec ma version d'assembleur 8086...


Message édité par thenutskiller le 14-01-2003 à 14:07:09
Reply

Marsh Posté le 14-01-2003 à 14:07:10    

drasche a écrit :


10 = 10 alors que 10H = 16.


euh, oui merde, je me souvenais plus, ça fait tellement lgt [:totoz]
 
effectivement, soit tu met 0Ah, soit tu laisses 10
 
sorry for the mistake :jap:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 14:08:43    

thenutskiller a écrit :


 
Cette fonction (MOVSB) n'est pas dispo avec ma version d'assembleur 8086...


8086 ? pq utilises tu un assembleur 8086 ??
 
si tu cherches un assembleur "contemporain", utilises MASM ou NASM


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 14:10:46    

J'utilises TASM, parce que je suis obligé...

Reply

Marsh Posté le 14-01-2003 à 14:13:31    

tu as mis la directive .386 au début de ton code ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 14:17:02    

Non... comme c'est pour un TP, je respecte les directives, sans modifier le squelette du programme...

Reply

Marsh Posté le 14-01-2003 à 14:23:03    

je veux rien dire mais il me semble pourtant bien que le MOVSB est une instruction compréhensible par le 8086 (j'ai pas mes grimoires pour vérifier) :sarcastic:

Reply

Marsh Posté le 14-01-2003 à 14:27:09    

Je viens de trouver qque chose: il y a une fonction MOVSB, mais sans arguments...

Reply

Marsh Posté le 14-01-2003 à 14:28:55    

ben il me semble aussi, mais moi non plus j'en suis pas sur !
mais je trouve ça complètement idiot de bloquer l'accès aux instructions des 386+ alors qu'il n'y a plus de 8086, 286, 386, 486 et autres sur le marché !


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 14:29:58    

thenutskiller a écrit :

Je viens de trouver qque chose: il y a une fonction MOVSB, mais sans arguments...


ben oui, MOVSB ne prend pas d'arguments !
 
edit: et MOVSB n'est pas une FONCTION, mais une INSTRUCTION


Message édité par Harkonnen le 14-01-2003 à 14:32:10

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 14:38:30    

Exemple d'utilisation de MOVSB pour copier une chaine de caractères :
 


Source db "chaine source$"
Dest   db 14 dup(0)
 
mov si, offset Source
mov di, offset Dest
rep movsb


 


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 14:41:04    

t'as oublié le positionnement du flag et de CX :sarcastic:


Message édité par drasche le 14-01-2003 à 14:42:15
Reply

Marsh Posté le 14-01-2003 à 14:47:36    

Peux-ton agir sur l'octet qui est copié (comme par exemple mettre en majuscule une minuscule) avec cette méthode?
Comment récupérer la taille effective de la chaine entrée par l'utilisateur?

Reply

Marsh Posté le 14-01-2003 à 14:54:46    

drasche a écrit :

t'as oublié le positionnement du flag et de CX :sarcastic:


Euh, oui, je rectifie (putain, je suis rouillé en asm moi :()
 


Source db "chaine source$"  
Dest   db 14 dup(0)  
 
mov si, offset Source  
mov di, offset Dest
mov cx, 14
rep movsb


 
par contre, inutile de tester le flag, car la présence de REP avant le MOVSB permet le test par le cpu de la valeur de CX, et stoppe la copie dés qu'il arrive à 0


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 14:59:35    

thenutskiller a écrit :

Peux-ton agir sur l'octet qui est copié (comme par exemple mettre en majuscule une minuscule) avec cette méthode?
Comment récupérer la taille effective de la chaine entrée par l'utilisateur?


la chaine destination est placée dans DI. Donc tu peux accéder à chaque caractère sans problème : [DI] => 1er car, [DI+1] => 2eme car, etc...
 
Pour récupérer la taille de la chaine entrée par l'utilisateur, tu fais la différence entre les 2 adresses (Dest - Source). Tu obtiens ainsi le nombre d'octets de différences, et donc la chaine pointée par Source


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 15:08:12    

Je ne comprends pas très bien ce que tu veux dire... j'ai fait cela:
 
       MOV AH,10
        MOV DX, offset Buffer
        INT 21H
 
 mov ah, 09h
 lea dx, newline  ; nouvelle ligne
 int 21h
 
 MOV SI, offset Buffer
 MOV DI, offset ChainCar
        MOV CX,0
 
 
 rep MOVSB
 
 
 
 MOV BX, offset ChainCar
 SUB BX, offset Buffer  
 mov ChainCar[BX],'$'
         
 
        MOV AH, 09
        mov DX, offset ChainCar
        INT 21H

 
Et le programme ne m'affiche que les 2 premier caractères...

Reply

Marsh Posté le 14-01-2003 à 15:14:11    

drasche a écrit :

REP MOVSB dest, source
 
c plus efficace qu'une boucle :o


 
perso j'optimiserais ca a coup de prefetch, de movntq, mais c pe de l'overkill :ange: :D
 

Reply

Marsh Posté le 14-01-2003 à 15:14:30    

il ne s'agit pas de tester le flag mais de le positionner, sinon on risque de copier un truc inconnu et de se manger une erreur système.  Au moyen de STD (SeT Direction) ou CLD (CLear Direction), ça vient de me revenir.  Je pense que dans le cas présent, il faut donc ajouter un CLD avant le REP MOVSB.
 
Ensuite CX ne doit pas être initialisé à zéro mais au nombre de bytes qui vont être déplacés (CX va être décrémenté à chaque itération, jusqu'à zéro).

Reply

Marsh Posté le 14-01-2003 à 15:15:50    

CX doit contenir le nombre de caractères que tu copies. Forcément, si tu le met à 0, ça va pas le faire :sarcastic:
 
Par contre, si tu pouvais utiliser une couleur un peu plus lisible, mes yeux t'en remercieraient :jap:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 15:18:32    

drasche a écrit :

il ne s'agit pas de tester le flag mais de le positionner, sinon on risque de copier un truc inconnu et de se manger une erreur système.  Au moyen de STD (SeT Direction) ou CLD (CLear Direction), ça vient de me revenir.  Je pense que dans le cas présent, il faut donc ajouter un CLD avant le REP MOVSB.
 
Ensuite CX ne doit pas être initialisé à zéro mais au nombre de bytes qui vont être déplacés (CX va être décrémenté à chaque itération, jusqu'à zéro).


Putain, oui, CLD, effectivement, j'avais oublié le CLD. Tu as raison, il faut un CLD avant le MOVSB :jap: (je suis vraiment rouillé en asm !!!)
 
Pour CX, grilled ;)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 15:21:42    

je m'en sors pas encore si mal je trouve, j'ai plus fait d'ASM depuis eeeeeuh 7 ans? :whistle:

Reply

Marsh Posté le 14-01-2003 à 15:24:25    

Pour CX, je dois d'abord savoir quelle est la longueur de la chaine entrée par l'utilisateur?

Reply

Marsh Posté le 14-01-2003 à 15:27:11    

drasche a écrit :

je m'en sors pas encore si mal je trouve, j'ai plus fait d'ASM depuis eeeeeuh 7 ans? :whistle:


Moi j'ai arrété l'ASM en 98, année ou j'ai stoppé mes activités de demomaker :'(
Il m'arrive d'en refaire pour le plaisir, et pour ne pas perdre la main surtout...


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 15:27:59    

thenutskiller a écrit :

Pour CX, je dois d'abord savoir quelle est la longueur de la chaine entrée par l'utilisateur?


cf ma réponse plus haut :sarcastic:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 15:33:42    

J'en suis arrivé à cela:

        MOV AH,10
        MOV DX, offset Buffer
        INT 21H
 
 mov ah, 09h
 lea dx, newline  ; nouvelle ligne
 int 21h
 
 MOV BX, offset ChainCar
 SUB BX, offset Buffer  
        MOV CX,BX
 
 MOV SI, offset Buffer
 MOV DI, offset ChainCar
 
 CLD
 rep MOVSB
 
 
 
 mov ChainCar[BX],'$'
         
 
        MOV AH, 09
        mov DX, offset ChainCar
        INT 21H

 
mais il ne m'affiche que les 2 premier caractères de la chaine entrée par l'utilisateur...

Reply

Marsh Posté le 14-01-2003 à 15:42:39    

Je trouve que pour un TP, on t'a déja pas mal aidé ! Surtout que ce genre de routine est archi simple.
 
Quand un résultat ne correspond pas à ce que tu souhaites, le mieux est d'utiliser un débugger, et de voir ce qui se trouve dans tes registres.
 
On t'a donné toutes les clés, maintenant c'est à toi d'ouvrir les portes.
 
Si tu cherches un debugger pas à pas, je te conseille SoftICE (très difficilement trouvable sur le net). Sinon, tu as TRW2000 qui est très bien aussi.
 
Ton prob vient surement d'un paramètre mal intialisé pour les services de l'int 21h, ou du fait que ta chaine contient le caractère '$' à la mauvaise place.
 
Ce ne sera pas te rendre service que de te macher le boulot.
 


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 14-01-2003 à 15:49:40    

Je vous remercie, mais je n'arrive toujours pas à placer le $ correctement...

Reply

Marsh Posté le 14-01-2003 à 16:01:50    

Comment déclares tu ChainCar, Buffer et newline ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed