Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would one use "movl $1, %eax" as opposed to, say, "movb $1, %eax"

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.

like image 636
Negative Acknowledgement Avatar asked Dec 14 '09 03:12

Negative Acknowledgement


3 Answers

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.

like image 174
Jason Avatar answered Oct 18 '22 13:10

Jason


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.

like image 44
Victor Shnayder Avatar answered Oct 18 '22 15:10

Victor Shnayder


%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.

like image 24
Aaron Klotz Avatar answered Oct 18 '22 15:10

Aaron Klotz