cs_rt15
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
11 juin 2007 à 08:51
Bon, comme BruNews a pas l'air de se décider, voyons ce que ça donne côté compilation.
Config :
VC2005 pro (MSDN AA).
Release.
Optimisation complète.
Privilégie le code rapide.
Jeu de caractère multi octet.
Compiler comme code C.
Convention en stdcall.
J'ai remplacé le :
if(!len) goto subEXIT;
malencontreusement oublié dans les modifs de coucou747 par un :
if(!len) return 0;
Une question : pourquoi s est const ?
Cela ne devrait pas nous empècher de le modifier ?
Mon main :
int __cdecl main(int argc, char * argv[])
{
char *s = "une phrase";
char d[20];
HANDLE hOutput;
DWORD nWritten;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
StrSubWithGoto(s, 2, 5, d);
lstrcat(d, "\n");
WriteConsole(hOutput, d, 6, &nWritten, NULL);
StrSubWithoutGoto(s, 2, 5, d);
WriteConsole(hOutput, d, 5, &nWritten, NULL);
return 0;
}
Débugueur/désassembleur : W32DASM.
Les deux routines ont été inlinées par le compilo.
Le tampon de réception est en esp+18.
eax pointera la chaîne source, ecx la chaîne de destination.
Le test sur la longueur à été supprimé puisque inutile dans ce cas particulier.
De même le test sur pos.
La valeur de retour n'est pas calculée puisque non utilisé.
Les add et les sub auraient dûes être logiquement des inc et des dec, plus compactes.
StrSubWithGoto :
mov edi, 5
mov esi, 2
mov eax, s
lea ecx, dword ptr [esp+18]
loop1:
if(*s++ == 0) goto subEXIT;
mov dl, byte ptr [eax]
add eax, 1
test dl, dl
je subEXIT
while(--pos);
sub esi, 1
jne loop1
loop2:
if((*p *s) 0) goto subEXIT;
mov dl, byte ptr [eax]
test dl, dl
mov byte ptr [ecx], dl
je subEXIT
p++; s++;
add ecx, 1
add eax, 1
while(--len);
sub edi, 1
jne loop2
subEXIT:
(..)
*p = 0;
mov byte ptr [ecx], 00
StrSubWithoutGoto :
Faudrat que l'on m'explique l'intérêt du lea ecx, dword ptr[ecx+00]...
Le mov edi, edi est lui aussi manifique...
mov edi, 5
mov esi, 2
mov eax, s
lea ecx, dword ptr[esp+18]
lea ecx, dword ptr[ecx+00]
loop1:
if(*s++ 0) { *p 0; return (p - szdst); }
mov dl, byte ptr[eax]
add eax, 1
test dl, dl
je trèsLoin
while(--pos);
sub esi, 1
jne loop1
mov edi, edi
loop2:
if((*p *s) 0) break;
mov dl, byte ptr [eax]
test dl, dl
mov byte ptr [ecx], dl
je subEXIT
p++; s++;
add ecx, 1
add eax, 1
while(--len);
sub edi, 1
jne loop2
subEXIT:
*p = 0;
mov byte ptr [ecx], 0
(..)
trèsLoin:
Comparatif :
Si on exclut les 2 instructions (très) bizarres, le code est quasi identique.
Le goto s'en sort donc un peu mieux dans ce cas précis, mais plutôt à cause du compilo qu'autre chose.
Mon compilo préféré s'est par exemple abstenu de générer ces deux lignes...
Je me demande si le seul vrai critère d'emploi ou pas du goto ne serait pas :
Mon chef aime-t-il les goto ?