As the title states, why would one use "movl $1, %eax" as opposed to, say, "movb $1, %eax", I was told that movl would zero out the high order bits of %eax, but isn't %eax a register that's equivalent to the size of the system's wordsize? meaning that movl is in actuality an integer operation (and not a long?)
I'm clearly a bit confused about it all; Thanks.
opposed to, say, "movb $1, %eax"
This instruction is invalid. You can't use eax with the movb instruction. You would instead use an 8-bit register. For example:
movb $1, $al
but isn't %eax a register that's equivalent to the size of the system's wordsize?
No. EAX will always be a 32-bit value, regardless of the system's register size.
You are confusing C variable sizes with register sizes. C variable sizes may change depending on your system and compiler.
Assembly is simpler than C. In GAS assembly, instructions are suffixed with the letters "b", "s", "w", "l", "q" or "t" to determine what size operand is being manipulated.
* b = byte (8 bit) * s = short (16 bit integer) or single (32-bit floating point) * w = word (16 bit) * l = long (32 bit integer or 64-bit floating point) * q = quad (64 bit) * t = ten bytes (80-bit floating point)
These sizes are constant. They will never be changed. al is always 8-bits and eax is always 32-bits.
On a 32 bit machine, %eax is a 4 byte (32 bit) register. movl will write into all 4 bytes. In your example, it'll zero out the upper 3 bytes, and put 1 in the lowest byte. The movb will just change the low order byte.
%eax
is a 32-bit register. To use a smaller width, you need %ax
for 16-bits. %ax
can be further divided into %ah
for the high byte of %ax
, and %al
for the lower byte. The same goes for the other x86 GPRs.
Looking at the Intel instruction set reference for the mov
instruction, I don't see a variant that can move a single byte into a 32-bit register -- it's probably interpreted as a move into %al
.
Since movl
is a 32-bit instruction, the values for the upper bytes will correspond to zeros in the case of an immediate value. If you were moving from memory you would be moving an entire 32-bit word.
%eax
is not zeroed out unless you either movl $0, %eax
, or if you xorl %eax, %eax
. Otherwise it holds whatever value was previously in there. When you movl $1, %eax
, you will end up with 0x00000001
in the register because the 32-bit instruction moves a 32-bit immediate value into the register.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With