copie de chaines de caractères - ASM - Programmation
Marsh Posté le 14-01-2003 à 12:02:18
Voilà le programme:
Citation : |
Mais ça ne marche pas... si vous avez une idée
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
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
Marsh Posté le 14-01-2003 à 13:53:02
drasche a écrit : REP MOVSB dest, source |
pour le
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
Marsh Posté le 14-01-2003 à 13:53:50
ça ne donne rien... il m'affiche des caractères bizarres...
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
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...
Marsh Posté le 14-01-2003 à 14:01:19
crotte j'ai pas mon code source ici pour le REP MOVSB
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:
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 si je veux quand même. (je vote le dernier jour )
Bon on va pas pourrir le topic pour ça hein!
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.
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)...
Marsh Posté le 14-01-2003 à 14:04:14
drasche a écrit : crotte j'ai pas mon code source ici pour le REP MOVSB
|
Cette fonction (MOVSB) n'est pas dispo avec ma version d'assembleur 8086...
Marsh Posté le 14-01-2003 à 14:07:10
drasche a écrit : |
euh, oui merde, je me souvenais plus, ça fait tellement lgt
effectivement, soit tu met 0Ah, soit tu laisses 10
sorry for the mistake
Marsh Posté le 14-01-2003 à 14:08:43
thenutskiller a écrit : |
8086 ? pq utilises tu un assembleur 8086 ??
si tu cherches un assembleur "contemporain", utilises MASM ou NASM
Marsh Posté le 14-01-2003 à 14:13:31
tu as mis la directive .386 au début de ton code ?
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...
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)
Marsh Posté le 14-01-2003 à 14:27:09
Je viens de trouver qque chose: il y a une fonction MOVSB, mais sans arguments...
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é !
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
Marsh Posté le 14-01-2003 à 14:38:30
Exemple d'utilisation de MOVSB pour copier une chaine de caractères :
|
Marsh Posté le 14-01-2003 à 14:41:04
t'as oublié le positionnement du flag et de CX
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?
Marsh Posté le 14-01-2003 à 14:54:46
drasche a écrit : t'as oublié le positionnement du flag et de CX |
Euh, oui, je rectifie (putain, je suis rouillé en asm moi )
|
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
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? |
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
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...
Marsh Posté le 14-01-2003 à 15:14:11
drasche a écrit : REP MOVSB dest, source |
perso j'optimiserais ca a coup de prefetch, de movntq, mais c pe de l'overkill
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).
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
Par contre, si tu pouvais utiliser une couleur un peu plus lisible, mes yeux t'en remercieraient
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. |
Putain, oui, CLD, effectivement, j'avais oublié le CLD. Tu as raison, il faut un CLD avant le MOVSB (je suis vraiment rouillé en asm !!!)
Pour CX, grilled
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?
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?
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? |
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...
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
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...
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.
Marsh Posté le 14-01-2003 à 15:49:40
Je vous remercie, mais je n'arrive toujours pas à placer le $ correctement...
Marsh Posté le 14-01-2003 à 16:01:50
Comment déclares tu ChainCar, Buffer et newline ?
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