Peut on mieux faire ?

spiky31 Messages postés 106 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 11 février 2008 - 18 févr. 2006 à 11:46
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 - 20 févr. 2006 à 10:18
Bonjour

Voila j'ai commencé ce matin a programmer en assembleur intel et j'aurais voulu avoir votre avis (Je me considére pas vraiment comme un noob vu que j'ai fais beaucoup de programmes en assembleur 68000 mais bon ...) :

J'ai fait une version de "strcpy" en assembleur quoique ce n'est pas mon but final (heureusement !!) mais c'est déja un début ...

voici le code :

__declspec(naked) void __fastcall myStrCpy(char *dest,char *src)
{
__asm
{
mov [esp - 4],eax
mov al,byte ptr[edx]
mov byte ptr[ecx],al
or al,al
jnz short L1
mov eax,[esp - 4]
ret 0
L1 :
mov [esp - 8],esi
xor esi,esi
L2 :
inc esi
mov al,byte ptr[edx + esi]
mov byte ptr[ecx + esi],al
or al,al
jnz short L2
mov esi,[esp - 8]
mov eax,[esp - 4]
ret 0
}
}

qu'en pensez vous ? peut on l'améliorer ?

Merci d'avance

16 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 févr. 2006 à 21:00
pourquoi toucher à ESI ???

#ifndef MCRASM_H
#define MCRASM_H


#ifndef BNINLINE
#ifdef __cplusplus
#define BNINLINE inline
#else
#define BNINLINE __inline
#endif /* __cplusplus */
#endif /* BNINLINE */


BNINLINE char* bnstrcpy(char *dst, char *src) // return ptr sur NULL final
{
__asm {
mov eax, dst
mov ecx, src
dec eax
LcpyLoop:
mov dl, [ecx]
inc eax
inc ecx
mov [eax], dl
or dl, dl
jz short LcpyOut
mov dl, [ecx]
inc eax
inc ecx
mov [eax], dl
or dl, dl
jz short LcpyOut
mov dl, [ecx]
inc eax
inc ecx
mov [eax], dl
or dl, dl
jnz short LcpyLoop
LcpyOut:
}
}

#endif

un strcpy doit être inliné (comme une macro), un appel de fonction coute cher.
bnstrcpy() retourne pointeur sur fin de copie, permet chainage sans reparcourir la chaine. C'est autrement moins couillon que strcpy qui retourne ce qu'on lui donne et donc qu'on avait déjà.

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
18 févr. 2006 à 21:32
salut,

mov [esp - 4],eax

acceder a une memoire non allouée est a mon avis une erreur meme si le mode protégé est sensé ne pas toucher a la pile utilisateur.

@++
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
19 févr. 2006 à 09:08
Ecrire sous ESP ne pose aucun problème tant qu'on ne fera pas un 'call' ou truc de ce genre faisant bouger ESP, c'est plus performant que 'push pop' mais bien entendu à réserver au mode protégé.

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
19 févr. 2006 à 12:51
salut,

et a ne surtout pas utiliser dans un kernel.

@++
0

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

Posez votre question
spiky31 Messages postés 106 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 11 février 2008
19 févr. 2006 à 13:14
Merci pour toutes ces précisions, je viens encore d'apprendre quelques trucs ...

j'ai juste une petite question BruNews :

pourquoi ton code plutot que celui la :

BNINLINE char* bnstrcpy(char *dst, char *src) // return ptr sur NULL final
{
__asm {
mov eax, dst
mov ecx, src
dec eax
LcpyLoop:
mov dl, [ecx]
inc eax
inc ecx
mov [eax], dl
or dl, dl
jnz short LcpyLoop
}
}

il semble fonctionner pareil ... ??
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
19 févr. 2006 à 13:24
Je déroule la boucle 3 fois donc 1 saut de code sur 3, appréciable en perf sur les longues chaines.

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
0
spiky31 Messages postés 106 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 11 février 2008
19 févr. 2006 à 13:37
Alors je viens de faire quelque tests et effectivement la version déroulée est beaucoup plus rapide que la version non déroulée c'est impressionant !!
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
19 févr. 2006 à 14:08
aligner les chaines sur 4 octets permet de faire une lecture DWORD et de travailler sur le registre ensuite.

@++
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
19 févr. 2006 à 15:06
Quand on chaine des trucs, on ne choisit pas la position donc alignement inconnu.

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
19 févr. 2006 à 16:09
le probleme ne vient pas de la taille alignée ou non de la chaine mais du buffer qui la contiendra ( pour eviter l'acces a une memoire non allouée )

@++
0
spiky31 Messages postés 106 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 11 février 2008
19 févr. 2006 à 17:13
ton idée n'est pas mauvaise du tout patatalo mais le test pour savoir quand on arrive en fin de chaine risque d'etre couteux
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
19 févr. 2006 à 18:05
mémoire non allouée ???
On est sensé s'adresser ici à des développeurs, pas des VBistes, on va donc considérer les buffers alloués comme il se doit sinon tout est perdu.

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
19 févr. 2006 à 22:58
absolument pas:

.1
mov edx,[ecx]
lea ecx,[ecx+4]
and dl,dl
mov [eax],dl
lea eax,[eax+1]
je .2
shr edx,8
mov [eax],dl
lea eax,[eax+1]
je .2
shr edx,8
mov [eax],dl
lea eax,[eax+1]
je .2
shr edx,8
mov [eax],dl
lea eax,[eax+1]
jne .1
.2
ret

@++
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
19 févr. 2006 à 23:25
et tu crois qu'avec des shr ça ira plus vite ???

ciao...
http://dev.winsysdev.com
BruNews, MVP VC++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
20 févr. 2006 à 00:45
si il n'y a que ca:

.1
mov dx,[ecx]
lea ecx,[ecx+2]
cmp dl,0
mov [eax],dl
lea eax,[eax+1]
je .2
cmp dh,0
mov [eax],dh
lea eax,[eax+1]
jne .1
.2
ret
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
20 févr. 2006 à 10:18
si cpu >= 486

.1
mov edx,[ecx]
lea ecx,[ecx+4]
cmp dl,0
mov [eax],dl
lea eax,[eax+1]
je .2
cmp dh,0
mov [eax],dh
bswap edx
lea eax,[eax+1]
je .2
cmp dh,0
mov [eax],dh
lea eax,[eax+1]
je .2
cmp dl,0
mov [eax],dl
lea eax,[eax+1]
jne .1
.2
ret

l'instruction bswap prends 1 clock et ne modifie pas les flags.

@++
0
Rejoignez-nous