Copier chaine [Résolu]

Signaler
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
-
 ToutEnMasm -
Lu,

Je débute en ASM et je cherche des exemples et des cours un peu partout.
Pour l'instant j'essaye d'apprendre a maitriser l'uitlité des registres mais aussi les variable.
En C, les types de variables sont tels que char [], char *, int, double, float.
Quel sont les équivalents en ASM ?

Aussi, est ce que quelqu'un pourrait me faire un exemple de fonction qui prend en parametre 2 chaines et qui copie la 1ere dans la deuxieme.

Merci par avance. Toute aide sera la bienvenue.

Shell

60 réponses

Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
tu lutilises comme ca :

char *s, buffer[200], coucou[] = "coucou\n", cestmoi[] = "c'est moi.";

s = bnstrcpy(buffer, coucou);
bnstrcpy(s, cestmoi);

MessageBox(0, buffer, 0, 0);

Voila, tu as eskivé un strcat ki parcourt la chaine pour rien ! gain de performance..Enfin ds l'exemple ke jT doné, pas tres significatif mais ds de longues boucles, tu vois vraiment la difference ! C pas du Brubru pour rien...

++
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
Coucou,

char coucou[12]; >> coucou db 12 dup(0);
char *coucou; >> coucou dd 0; pointeurs 4 octets donc un double mot
int coucou; >> coucou dd 0; int 4 octets donc un double mot
double coucou; >> coucou dq 0.0;double 8 octets donc un qword.

APres pour la fonction, j'etais en train de ten faire une, mais pas sur du tt kel fonctionne, donc je prefere te dire que Brunews en a codé une, tu peux la trouver sur cppfrance, c'est bnstrcpy.

Voila, en esperant avoir pu t'aider..

++
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Yep j'ai regardé ce que tu m'as dis.
j'ai essayé un truc du genre mais ca marche pas, j'ai une erreur a la compilation :
/Code...
.data
Msg db 50 dup (0)
Txt db 50 dup (0)

.code
start:

mov Msg[0], Txt[0]
.../Code

Et j'ai l'erreur suivante :

"D:\ASM\PrintString\Main.asm(17) : error A2070: invalid instruction operands

Comment faire pour copier le 1er élément d'un tableau dans un autre tableau de meme type et de meme taille ?

Shell
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
Il faut passer par un registre intermediaire :

mov dl, [ecx]
mov [eax], dl

ca devrait passer, mais t'as regardé la source de Brubru ?
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Oui je l'ai regardé mais j'y ai rien compris ou du moins pas grand chose.
En fait pour fixer les connaissances de base sur les registres, dans quel cas utilise t'on EAX, EBX, ECX, EDX, ESI, et EDI?
Et surtout comment les utilise t'on ?

Pourquoi préféré EAX a EBX ou autre ?

J'ai plein de ptite question comme ca qui me trote dans la tete.

Shell
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
jV repondre en parti paske mes connaissances sont bien maigres en asm...

Je pense qu'utiliser eax, ecx, et edx est du au fait qu'on a pas besoin de les restaurer apres utilisation, contrairement a EDI, ESI et EBX oci ! Enfin, jmexprime ptet mal, atta ke Brubru passe par la, il t'explikera bocou mieux ke je le ferai. Par contre, si tu as des pb avec sa fonction, demande moi, j'ai passé du temps a la comprendre moi oci, et ji suis arrivé dc n'hésite pas...

++
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Yep je vais attendre BruNews pour quelques explications sur l'utilisation des registres.

Par contre je viens de lire et relire la fonction de BruNews et je pense avoir compris pas mal de chose, sauf peut etre une!

Pourquoi réitère t'il 3 fois les changements de registres en les comparants ?
Une seule fois n'aurait elle pas suffit en bouclant dessus jusqu'a arriver a la fin de la chaine ?

Et quand il utilise dec, il decremente le pointeur, mais dans ce cas comemnt fait il pour aller au bout de la chaine en decrementant ?

Shell
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
Uè moi oci ca ma semblé bizar, mais en fait, c paskil a deroulé la boucle, au lieu de faire 3sauts, il nen fera k1, c une technik d'optimisation made in brubru.
Et pour ce ki est de l'utilisation de dec, je crois (si jme souviens bien) kil ne fait ca kune seule fois, au debut, c pour ka la fin, il renvoie une valeur pointant sur le zero final de la chaine.
Voila, en esperant t'avoir aidé

++
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Oki,
C'est deja beaucoup plus clair.
J'essaye donc de copier le premier caractere d'un db dans un dd, je compile je n'ai aucune erreur mais le prog plante!
Ou est l'erreur ???
.data
txt   dd 12 dup   (0)
msg   db "Salut!",0 
.code 
start: 
   mov eax, txt
   mov ecx, offset msg
   mov dl, [ecx]
   mov [eax], dl
   add eax,0

   invoke MessageBox, NULL, addr txt, addr msg, MB_OK
   invoke ExitProcess,0 
end start


Shell
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
mov eax, offset txt

ca passe nan ?

Et pkoi ce add eax, 0 ??? ne sert a rien, et puis si jpeu te donner un conseil, ki n'est kune kestion de gout, enleve ces invoke, ki ne font ke denaturer le vrai assembleur ... Mais fais comme tu veux !

++
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Ah ben ca y est ca marche.
Manquait ce "offset".
Je mets add eax, 0 pour le caractere nul de fin de chaine, mais apparement ca marche très bien sans.

Sinon pour les invoke, ca me simplifie la taches pour l'instant, c'est tout de meme plus court que d'aligner des push et d'appeller un call.
En plus avec les invoke lors de la compilation il y a une verification des parametres ce qui evite les erreurs.

Voila an tous cas pour l'instant j'arrive a copier un caractere.
Comment faire pour detecter la fin de la chaine et stopper une boucle ?

Shell
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
De la bal je viens de trouver tout seul le système :D
Ah il est bien se language malgrè que j'y comprene pas grand chose!

Voila le code en entier :
.386 
.model flat, stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib 
 
.data
txt   dd 12 dup   (0)
msg   db "Salut!",0 
.code 
start: 
   mov eax, offset txt
   mov ecx, offset msg
 DBoucle:
   mov dl, [ecx]
   mov [eax], dl
   ;add eax,0
   inc eax
   inc ecx
   cmp dl, 0
   je FBoucle
   jmp DBoucle
FBoucle:
   

   invoke MessageBox, NULL, addr txt, addr msg, MB_OK
   invoke ExitProcess,0 
end start 


Shell
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
add eax, 0 n'ajoutera jamais un zero a la fin de la chaine ! cette instruction est la pour additionner des nombres, et pas concaténer des chaines, il faut ke tu fasses mov dword ptr[eax], 0.

voila, bonne continuation !

++
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Hum,
Oki compris. Je me sidais aussi.
Sinon, quel est la particularité de la fonction de BruNews ? Quel interet de renvoyer un pointeur sur le zéro final de la chaine ?

Shell
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
En renvoyant un pointeur sur le zero final, plus besoin d'utiliser strcat pour concatener des donnees, strcat parcourt la chaine donc perte de performance, on a fait des tests, et c vraiment bocou plus performants kan tu utilises ca ds une longue boucle.
Je lutilise kasiment tt le temps moi, enfin kan j'en ai besoin.
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Oui mais si j'utilise sa fonction pour copier une chaine dans une autre, ensuite je vais me retrouver avec un pointeur sur une fin de chaine, et dans ce cas comment je pourrai revenir au pointeur initiale si je veux afficher ma chaine dans un MessageBox par exemple ?

Shell
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Ah ok j'avais pas fait attention.
En fait c'est le ret qui retourne le pointeur sur la fin de la chaine.
Mais ca ne change pas le pointeur de début de chaine.
Clair que c'est beaucoup plus pratique.
Pas bete du tout cette fonction ou plutot BruNews.

Merci pour ton aide.
Si ya des souci je viendrais t'embeter un temps soit peu.

Shell
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
21
DeAtHCrAsH> faut aligner les donnees correctement au minimum sur un multiple de 4, y a pas de compilo ici pour le faire a ta place.

si besoin de 50 octets alors tu en definis 52.

Si on veut se simplifier la vie et des controles a la compil alors on utilise un compilo et on ecrit donc en C. ASM est le domaine de la pure optimisation sinon aucune raison de perdre du temps a l'ecrire, VS 2003 par exemple le fait tres bien. Ce n'est pas avec des 'invoke' et autres facilites que tu controleras la bonne parallelisation des instructions.

ciao...
BruNews, Admin CS, MVP VC++
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
J'ai senti l'arrivée de Brunews : 2sources ont mysterieusement disparu sur cppfrance.com...;)
DeathCrash > pour ne pas encombrer le forum, si tu veux kon continue notre apprentissage ensemble, envoie des messages privé, sera plus simple. Et ds le pire des cas, ya le forum.
Voila, ravi d'avoir pu aidé (surtt kan c de l'asm !)

++
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
BruNews> ok, pour le placament tu m'avais deja expliqué que sur vc++ le compilo s'en charger. Je croyais que ca le fesait aussi en ASM.
Pour ce qui du invoke il est sure que des push et des call sont plus longs a écrire mais si tu me dis que les invoke reste limite alors j'en ferais abstraction. AlexMan m'avait deja fait la remarque.
En pratiquant on se rend compte que finallement l'ASM et le langage le plus proche de la réalité concernant la structuration et l'utilisation des regsitres & co.
Merci en tout cas, je commence a comprendre comment programmer en ASM. Ca va aussi beaucoup m'aider pour le C/C++, surtout pour faire des codes plus propres et surtout plus otpimisés!

Shell