Such small snippets are not too hard to decompile manually. Let's try it.
You have already figured out that cl
holds a character, this means that eax
where it's read from is a pointer to a character array. Let's call it p
. Now, let's do a dumb translation for every assembly statement to C:
l1: ; l1:
mov cl, [eax] ; cl = *p;
cmp cl, ' ' ; if ( cl < ' ' )
jb short l2 ; goto l2
cmp cl, ',' ; if ( cl != ',' )
jnz short l3 ; goto l3
l2: ; l2:
mov byte 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
And cleaned up:
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;
Now, let's have a look at the second if
. It has the following form:
if ( condition )
goto end_of_if;
<if body>
end_of_if:
And here's how we can get rid of the goto
:
if ( !condition )
{
<if body>
}
Applying it to our snippet:
l1:
cl = *p;
if ( cl < ' ' )
goto l2;
if ( cl == ',' ) {
l2:
*p = ' ';
}
cl = *(p+1);
p = p + 1;
if ( cl != 0 )
goto l1;
Now, how we can get rid of goto l2
? If you look at it carefully, you can see that the body at l2
will get executed if either cl < ' '
or cl == ','
. So we can just combine the two conditions with a logical OR (||
):
l1:
cl = *p;
if ( cl < ' ' || cl == ',' ) {
*p = ' ';
}
cl = *(p+1);
p = p + 1;
if ( cl != 0 )
goto l1;
Now we have one goto
left. We have: 1) label at the beginning of a statement block 2) check at the end of the block and 3) goto to the start of the block if the check succeeded. This is a typical pattern of a do-while
loop, and we can easily convert it:
do {
cl = *p;
if ( cl < ' ' || cl == ',' ) {
*p = ' ';
}
cl = *(p+1);
p = p + 1;
} while ( cl != 0 )
Now the code is almost nice and pretty, but we can compress it a bit more by substituting equivalent statements:
do {
if ( *p < ' ' || *p == ',' )
*p = ' ';
cl = *++p;
} while ( cl != 0 )
And, finally, the last assignment can be moved into the condition:
do {
if ( *p < ' ' || *p == ',' )
*p = ' ';
} while ( *++p != 0 )
Now it's obvious what the code is doing: it's going through the string, and replacing all special characters (those with codes less than 0x20 aka space) and commas with the spaces.