Strrev

Signaler
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
-
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
-
Je regarde le fichier strrev.asm qui est utilisé au moins pour les debogages et je remarque que c'est une traduction d'un algorithme écrit en C qui est utilisé. Pourtant, j'ai l'impression qu'il serait plus interessant d'utiliser la structure de pile dont on dispose en assembleur, car elle donne de meilleurs résultats d'après mes tests. Est-ce que je me trompe, ou le code fourni par vs pour strrev est il médiocre?

Pour info voici le strrev que j'ai fait, et qui donne le même résultat que l'original si les 2 args sont égaux, mais plus rapidement en version release

inline char* strrev(char *dst, char *src)
{
  __asm 
  {
    mov   eax, dst
    mov   ecx, src
    mov   dl, 0
  boucle1:
    push  edx
    mov   dl, [ecx]
    inc   ecx
    or    dl, dl
    jnz   boucle1
  boucle2:
    pop   edx
    mov   [eax], dl
    inc   eax
    or    dl, dl
    jnz   boucle2
  }
}


Peut être que le "problème" vient de la taille limitée de la pile et donc ma fonction ne marcherait plus avec de longues chaines

7 réponses

Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
A koi te servent les push edx et pop edx, tu ne ten sers pas ! jme trompe ?
Ca faisait un moment kon tavait pas vu, jvois ke ta taffé le boukin d'asm..

++
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Oui je crois que tu te tompes: j'utilise dl
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
En voila une autre forme.

__inline char* strrevASM(char *dst, char *src)
{
__asm {
mov eax, dst
mov ecx, src
push eax
xor edx, edx
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:
pop edx ; *dst
dec eax
xor ecx, ecx
strrv:
cmp edx, eax
mov cl, [eax]
mov ch, [edx]
jae short revOut
mov [edx], cl
mov [eax], ch
inc edx
dec eax
jmp short strrv
revOut:
}
}

ATTENTION, je n'ai pas assure le pointeur en retour, sur quoi ?
Tu passes les pointeurs, donc tu les as deja, retour me semble inutile.

ciao...
BruNews, Admin CS, MVP Visual C++
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Tiens je remarque que tu écris 3 fois la même chose alors qu'une seule suffirait. C'est vrai que ca a l'air plus rapide, mais je ne comprends pas pourquoi (j'ai vu que tu avais fait pareil dans ta fonction bnstrcpy)
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
deroulage de boucle, vaut mieux effectuer un saut de code 1 fois plutot que 3.
Gaffe le reverse en bas n'est pas terrible, tape a la sauvage va vite. Affecter sur cl puis sur ch en instruction suivante provoque un AGI STALL a tout coup.

ciao...
BruNews, Admin CS, MVP Visual C++
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
un AGI STALL??
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
cycles de penalite dus a une mauvaise suite des instruction.
Terminologie des manuels Intel.

ciao...
BruNews, Admin CS, MVP Visual C++