Trying to narrow my question down so I can get past this hurdle. This isn't helping me much.
I am running NASM to see what the output of assembly is in terms of hex.
test:
@nasm -f macho64 test.asm
@objdump -x86-asm-syntax=intel --full-leading-addr -d test.o
.PHONY: test
In there I have some stuff, one of which is this:
add cl, 2
It outputs as:
80 c1 02
Looking at the Intel Manuals, I go to the ADD section, where it shows this:
80 /0 ib
That looks close enough, the 80
is there, and the ib
is my number 2
immediate value. But how to calculate this c1
from the /0
?
The docs say:
/digit — A digit between 0 and 7 indicates that the ModR/M byte of the instruction uses only the r/m (register or memory) operand. The reg field contains the digit that provides an extension to the instruction's opcode.
My questions are:
- Why did the assembler decide to put a ModR/M byte here?
- What does "uses only the r/m (register or memory) operand" mean? What operand, is it saying it recognizes there is a register
cl
and an immediate2
, and so it choosescl
because it is a register? - "The reg field contains the digit that provides an extension to the instruction's opcode." Hmm? What does this mean? All that I can about gather from this is,
/0
means it's the 0th register? That doesn't work out though, seems wrong. - Table 2-1 has the value
c1
in it, which aligns with thecl
register under the "Effective Address" header. Don't know what that means though. The corresponding R/M bit is right there at001
, and the column it's in is0
. Though none of that means much to me yet.
How do I convince myself that this c1
byte is correct? How do I read all the signs from the various tables, how could I deduce it myself from just looking at the assembly and the Intel tables?
/0
: duplicate of How to read the Intel Opcode notation (my answer specifically addresses exactly what the/number
means as opposed to/r
.) – Vainglorious