-->

Error moving a constant byte value into

2020-03-30 02:50发布

问题:

I'm working through Computer Systems, A Programmer's Perspective (3rd edition), and Practice Problem 3.3 contains the following line:

movb $0xF, (%ebx)

I'm supposed to find out what's wrong with this line of x86-64 assembly, and the answer key states: "Cannot use %ebx as address register", which doesn't make sense to me. My understanding is that this line intends to copy 0xF to a location in main memory, however %ebx is a 32-bit register, memory addresses are 64 bits wide on 64-bit machines, and so %ebx cannot hold a memory address, therefore it cannot be dereferenced (dereferencing is what the parentheses around %ebx represent, correct?). However, looking a few pages back in the book (page 183, if you have it) there is an example detailing the five mov operand--destination combinations, one of which is:

movb $-17, (%esp)         Immediate--Memory, 1 byte

%esp is a 32-bit register just like %ebx! And this example shows a byte value being moved to a dereferenced 32-bit register! Which doesn't make sense to me, because how can %esp contain a 64-bit address? Do I completely misunderstand assembly?

回答1:

You are right that,

movb $-17, (%esp)         Immediate--Memory, 1 byte

should not be allowed. In fact the authors have posted this as a typo. Check out their errata list (Ctrl-F for "p. 183").



回答2:

For 64-bit x86; there is nothing wrong with the instruction movb $0x0F, (%ebx). It assembles to 0x67, 0xC6, 0x03, 0x0F.

The book is wrong.

Note that all instructions can be bugs (simple example: using add when you wanted to use sub), and movb $0x0F, (%ebx) may be a bug (e.g. maybe the value was supposed to be 0xFF, maybe it was supposed to use a different register, maybe it was supposed to use rbx, maybe it was supposed to be a lea, ..). This doesn't mean that it's always a bug (e.g. 32-bit addresses are perfectly legal and sometimes desirable in 64 bit code).