1

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
jne XXXXX
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?

5
  • Its loading one byte from memory address pointed by value stored inne eax. Ecx = (char)*eax
    – malikcjm
    Commented Jan 17, 2018 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 * Commented Jan 19, 2018 at 21:15
  • I have one more question: Is the reconstruction to "||" correct?, or should it be a "&&"? Commented Jan 23, 2018 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
    Commented Jan 24, 2018 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. Commented Jan 24, 2018 at 9:12

1 Answer 1

3

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 and acknowledge you have read our privacy policy.

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