2

I have the following assembly line(I also added a C code implementation how I would do it in C):

     .................
A:   MOVSX EAX, BYTE PTR DS:[ECX]     |   while(ecx != NULL){
     ADD EDX, EAX                     |   
     INC ECX                          |   char *eaxPtr = *ecx;
     CMP BYTE PTR DS:[ECX], 0x0       |   int  edxValue += *(int *)eaxPtr;
     JNZ SHORT A                      |   ecx++;
     ADD EDX,0xB                      |
     MOV EAX,EDX                      |   }
     SUB EAX,0xB                      |   int eaxValue = edxValue;
     RETN                             |

The thing is that I have stored the string "30;,;1,73,:2" in the register ECX. What the routine above does is to go through the string and add the components of the string like 30 or the ANSCII representation of for example ; and so on in the register EDX. As result, I have the value 00000264 in EDX. What I do not understand is the end of the assembly line. Especially the lines:

     ADD EDX,0xB                      
     MOV EAX,EDX                      
     SUB EAX,0xB 

Why we first add 0xB to the register edx, then store it to eax, and then subtract 0xB from eax ? The whole is equivalent to the line:

     MOV EAX,EDX

Does somebody know why the compiler do it like that ? Because of optimization ? Or there any other reasons?

By the way: Is my C code implementation correct ?

1

The assembler code you posted is a do-while loop, not a while loop. I guess there's a few instructions in front of it that belong to the function but which you didn't post.

Unfortunately, you didn't post the preceding instructions, so we can just assume there was something there. For example, the programmer might have wanted to return -11 as an error code for an empty string, as in:

int sum=0;
if (*ecx) {
    do {
        sum+=*ecx;
        ecx++;
    } while (*ecx != '\0');
    sum+=11;
}
return sum-11;

However, this is guesswork, because your code doesn't show the if condition. How anyone would want to write his sourcecode like this, i don't know.

I could think of three reasons for the compiler to produce this code:

  1. No optimizations at all, and source code like mine above
  2. Intelligent avoidance of a conditional jump (these are evil because the processor instruction pipeline must be cleared if branch prediction fails), although i can't imagine a source code that would use it here.
  3. Optimization for space. Replace, in my example above, the sum+=11 with return sum. This would translate into a MOV EAX, EDX and RETN. ADD EDX, 0XB needs a byte less and accomplishes the same.

Edit: I just tested it: MOV EAX, EDX and RETN need 3 bytes, ADD EDX, 0xB needs 3 bytes as well. So Optimization for space is not an issue here.

1

The other answer is good and relatively complete, but there may be one other reason such code is used, and that is to obfuscate the code for the purpose of helping to prove future patent infringement or copyright violation. Because it's certainly not a usual way to do this operation, any code which duplicates it verbatim would likely be used in a court of law as evidence of copying.

See this article on software watermarking for a survey of current techniques and motivations for using them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.