I just started learning about reconstructing C code from assembler instructions.

I have the following piece of assembler code:

mov eax dword ptr [ebp+8]
add eax, dword ptr[ebp-4]
movsx ecx, byte ptr [eax]
test ecx, ecx
comp dword ptr [ebp-4], ffh
jle XXXX

I want to reconstruct the condition of these lines but I have some problems or things I am not sure about: I re-constructed the following:

Let,ebp+8= param1 and ebp-4 = i

if(param1[i]!=’\0’ || i<=0xff){

But I am wondering about this line:

movsx ecx, byte ptr [eax]

As I understand movsx it moves a signed value into a register and sign-extends it with 1. Thus, ecx shouble look something like 0xFFFFFF<eax>. Because only the lower bytes (byte ptr eax) of eax are moved and ecx is 1 extended. Where am I wrong?

  • Its loading one byte from memory address pointed by value stored inne eax. Ecx = (char)*eax
    – malikcjm
    Jan 17 '18 at 16:16
  • and it will become 0xFFFFFFxx only if the bit 7 of [eax] is set, otherwise it will be 0x000000xx. The point being that the array being read has been defined as a signed char * Jan 19 '18 at 21:15
  • I have one more question: Is the reconstruction to "||" correct?, or should it be a "&&"? Jan 23 '18 at 10:52
  • There is not enough context in the disassembly you gave to say definitively (i.e. where are the jumps going to and what code is being executed for each condition). In general for a null-terminated string/array, it would be if (array[i] != 0 && i < MAXCOUNT) -- AND instead of OR
    – cimarron
    Jan 24 '18 at 8:51
  • @cimarron the jne jumps right after the jle. The jle jumps to the function prolog. I know that usually it would be if (array[i] != 0 && i < MAXCOUNT) but to me it looks differently. Jan 24 '18 at 9:12

You may want to familiarize yourself with two's complement notation. It will only extend the sign bit (msb) into the larger register. So, the msb will be extended into all the additional bits -- sxxxxxxx -> sssssssssssssssssssssssssxxxxxxx

For example, if the byte value pointed to by eax was 1 (0b00000001), ecx would be 1 (0b00000000000000000000000000000001). Similarly, if it was the most positive number possible in a two's complement byte, 127 (0b01111111), ecx would be 127 as well (0b00000000000000000000000001111111).

Where the sign extension is needed is to maintain the value for negative numbers. If the value were -1 (0b11111111), then if you just simply zero-extended into a 32-bit value you would get 255 (0b00000000000000000000000011111111) in ecx instead of -1 (0b11111111111111111111111111111111).

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.