Ces petits extraits ne sont pas trop difficiles à décompiler manuellement. Essayons-le.
Vous avez déjà compris que cl
contient un caractère, cela signifie que eax
d'où il est lu est un pointeur vers un caractère tableau. Appelons cela p
. Maintenant, faisons une traduction stupide pour chaque instruction d'assembly en C:
l1:; l1: mov cl, [eax]; cl = * p; cmp cl, ''; if (cl < '') jb short l2; goto l2cmp cl, ','; if (cl! = ',') jnz short l3; aller à l3l2:; l2: octet mov ptr [eax], ''; * p = '' l3:; l3: mov cl, [eax + 1]; cl = * (p + 1) inc eax; p = p + 1 test cl, cl; if (cl! = 0) jnz short l1; goto l1
Et nettoyé:
l1: cl = * p; if (cl < '') goto l2; if (cl! = ',') goto l3; l2: * p = ''; l3: cl = * (p + 1); p = p + 1; if (cl! = 0) goto l1;
Maintenant, jetons un coup d'œil au deuxième if
. Il a la forme suivante:
if (condition) goto end_of_if; <if body>end_of_if:
Et voici comment nous pouvons nous débarrasser du goto
:
if (! Condition) {<if body> }
En l'appliquant à notre extrait de code:
l1: cl = * p; if (cl < '') goto l2; si (cl == ',') {l2: * p = ''; } cl = * (p + 1); p = p + 1; if (cl! = 0) goto l1;
Maintenant, comment pouvons-nous nous débarrasser de goto l2
? Si vous l'examinez attentivement, vous pouvez voir que le corps en l2
sera exécuté si soit cl < ''
ou cl == ','
. Nous pouvons donc simplement combiner les deux conditions avec un OU logique ( ||
):
l1: cl = * p; if (cl < '' || cl == ',') {* p = ''; }
cl = * (p + 1); p = p + 1; if (cl! = 0) goto l1;
Il nous reste maintenant un goto
. Nous avons: 1) une étiquette au début d'un bloc d'instructions 2) une vérification à la fin du bloc et 3) un retour au début du bloc si la vérification a réussi. C'est un modèle typique d'une boucle do-while
, et nous pouvons facilement le convertir:
do {cl = * p; if (cl < '' || cl == ',') {* p = ''; } cl = * (p + 1); p = p + 1; } while (cl! = 0)
Maintenant, le code est presque beau et joli, mais nous pouvons le compresser un peu plus en substituant des instructions équivalentes:
faire {si (* p < '' || * p == ',') * p = ''; cl = * ++ p;} while (cl! = 0)
Et, enfin, la dernière affectation peut être déplacée dans la condition:
do {if (* p < '' || * p == ',') * p = '';} while (* ++ p! = 0)
Maintenant c'est évident ce que fait le code: il passe par la chaîne et remplace tous les caractères spéciaux (ceux avec des codes inférieurs à 0x20 aka espace) et les virgules par les espaces.