cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 juin 2013
-
18 déc. 2006 à 18:02
cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 juin 2013
-
19 déc. 2006 à 21:29
Bonjour à tous,
A vrai dire je suis plutôt nouveau en asm et pas très bon lol. Mais bon, faut bien commencer un jour hein.
Pour me faire la main, j'ai écrit une petite méthode qui permet d'inverser une chaîne de caractère...
J'aimerais savoir si on peut faire mieux (sûrement que oui) et que les connaisseurs me corrigent
Merci d'avance
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 19 déc. 2006 à 21:24
J'avais lu ta question comme d'hab un peu trop vite...
Tu voulais une inversion mais dans un autre buffer.
La routine retournera non pas la longueur qui risquerait fort de ne pas servir à grand chose mais plutot le terminateur null final, permettra un chainage direct si besoin et la longueur peut être sue illico aussi (fin - deb comme fait dans la routine):
__declspec(naked) char* __fastcall bnCpyRevStr(char *pdst, char *psrc){ // ECX pdst, EDX psrc
__asm {
mov eax, ecx
cmp byte ptr[edx], 0
je short cpyrevEXIT
mov ecx, edx
mov [esp-4], ebx
goOUT:
add edx, 1
cmp byte ptr[edx], 0
jne short goOUT
mov ebx, edx
sub edx, ecx ;// len = c - psrc
sub ebx, 1
fromSRC:
mov cl, [ebx]
mov [eax], cl
sub ebx, 1
add eax, 1
sub edx, 1
jnz short fromSRC
mov ebx, [esp-4]
cpyrevEXIT:
mov byte ptr[eax], 0
ret 0
}
}
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 19 déc. 2006 à 20:37
Calcul de longueur est totalement inutile, une chaine doit finir par un 0, suffit de mettre un pointeur sur le dernier char.
Cette routine se fait tranquille avec les 3 registres généraux et donc rien à PUSHer POPer.
Mettre de l'asm dans une fonction en C est la pire des solutions, ça empêche toute optimisation du compilo. Si on la fait en asm alors FULL asm ou rien.
__declspec(naked) void __fastcall bnRevStr(char *psz)
{ // ECX = psz
__asm {
cmp byte ptr[ecx], 0
mov eax, ecx
je short revEXIT
goOUT:
add ecx, 1
cmp byte ptr[ecx], 0
jne short goOUT
goREV:
sub ecx, 1
cmp eax, ecx
jae short revEXIT
mov dl, [eax]
mov dh, [ecx]
mov [eax], dh
mov [ecx], dl
add eax, 1
jmp short goREV
revEXIT:
ret 0
}
}