Lets say we have this code below where val1, val2, and sum are 32 bits and BX is the BX register.
sum = (val1 + BX) - val2
When writing the code and using the BX register can we use EBX
directly instead of using movzx EBX, BX
?
Short answer is no.
BX
is 16-bit value and EBX
is 32-value. While they can represent the same number, there's no requirement that they do. Storing into BX doesn't modify the full EBX
, so if you don't know how BX
got its value, you cannot assume EBX
holds the same number — we only know for sure that just the low 16 bits are the same.
Note that when mixing data sizes, you need to be fully aware of sign! For example, let's take the 16-bit number 0xffff. If this number is meant to be understood as signed, then the 32-bit equivalent is 0xffff ffff (e.g. -110). Whereas if this number 0xffff is meant to be understood as unsigned, then the 32-bit equivalent is 0x0000 ffff (e.g. 6553510).
The instruction movzx
zero extends so as to assume the original BX
value as unsigned. While the instruction movsx
would be used if we assume the original BX
value is signed. After one of those instructions, the numeric value in BX
and EBX
will be the same number, if you knew and applied the proper signed-ness.
If you don't know the signed'ness of BX
, then the problem is ambiguous.
The way we usually find out the signed'ness of a value is to be told — typically by a programmer, via a variable declaration using a data type in C or other language. The type of the variables are remembered and translated by a compiler into appropriate instructions such as movsx
and movzx
, when needed to extend a 16-bit value for participation in 32-bit arithmetic. So, a programmer makes a program, which informs the compiler what to do. In case of a snippet like you're showing there's missing information (e.g. type declarations) that a compiler (or assembly programmer) would have were it complete and compile-able.
(You also have to consider whether you are allowed to modify EBX
, I would think that usually in the context of a code snippet, the answer would be yes, here since BX
already has a value of interest. But, to be clear you could send the extended value to another register, such as movzx EAX, BX
— don't have to sign/zero extend into the same register.)