Mov is making me crazy


MOV* (Intel Sytnax) has been driving me crazy for a little bit…

What in the world are the differences between MOV, MOVZX, and MOVSX?

I need to write a short post so that (1) I remember (2) I remember


mov: Good ol’ basic mov. Moves one thing to another


movzx: moves an unsigned value into a register and Zero-eXtends it with 0.

Why is this useful?

Take into consideration the following assembly code:

movzx ecx, byte ptr [eax]

movzx allows us to move one object that is a different size into a larger one (it will zero out the rest of the register). The above code is equivalent to:

xor ecx, ecx followed by mov cl, byte ptr [eax]

It is especially useful when we want to get a single character from another register (as our example does). If we were to do mov ecx, byte ptr [eax], I believe that there would be a size mismatch (tested on nasm).


movsx: moves an unsigned value into a register and Sign-eXtends it with 1.

Why is this useful?

There may be cases where we cannot use movzx. For example, the byte that we are moving to ecx (prior example) may be a signed value. This is where movsx comes in. The byte will be moved to ecx (at the least significant bytes) and the rest is filled with its sign.