2

I have the following disassembly:

mov BL, [EAX]
inc EAX
mov [EDX], BL
inc EDX

I could see this being the result of:

uint8_t foo = bar;
++bar;
uint8_t tmp = foo;
++foo;

But this assumes C99. Is there some other C construct that could produce the code above?

  • 7
    The infamous strcpy loop, *dst++ = *src++ ? – DCoder Mar 6 '14 at 17:01
  • What's tripping me up is that I had thought that the MOV instruction was limited so that the operands had to have the same size? This looks like I'm asking "Move a 32b value into the lower 8b of the EBX register." – avgvstvs Mar 8 '14 at 16:34
  • 1
    [EDX] does not stand for "the EDX register". It stands for "the address pointed to by the EDX register". The constrained you mentioned is valid, and in this case the instruction mov [EDX], BL is interpreted as "move the lowest byte of the EBX register to the byte at the address pointed to by (the value of) the EDX register." – DCoder Mar 8 '14 at 17:31
  • DCoder, would you care to post your comment as an answer so I can give due credit? – avgvstvs Mar 10 '14 at 16:48
6

If you just want the answer without the explanation, scroll to the bottom of this post.


The [register] notation stands for "take the value stored in register and interpret it as an address". If the addressed entity size is ambiguous, it can be clarified using DWORD PTR [register] for DWORD-sized pointers (and similarly for other pointer sizes).

mov BL, [EAX]

This line treats the value in the EAX register as a pointer to a single byte (the size of BL), reads a byte from that address and stores it in BL.

inc EAX

This line increments the value of EAX, effectively advancing to the next byte.

mov [EDX], BL

This line treats the value in the EDX register as a pointer to a single byte (again, the size of the other operand tells us this), and writes a byte that is stored in BL to that address.

inc EDX

This line increments the value of EDX, advancing to the next byte.

With all this information, we can see that this sequence basically copies a byte from one address to another. Most likely it is used in a loop such as string copy or memory copy. If there's a line similar to test BL, BL afterwards to determine if the copied byte was NULL, it's most likely a string copy; if there's a length/address check instead - it's probably a memory/buffer copy that works on a specified amount of bytes.


In C parlance, this can be represented as:

char t; // BL
char *src; // EAX
char *dst; // EDX

// initialize src and dst here

t = *src;
++src;
*dst = t;
++dst;

Or, as K&R put it ever so tersely:

*dst++ = *src++;

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.