Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

assembly - Why does `add cl, 2` print `80 c1 02` in x86 hex?

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:

  1. Why did the assembler decide to put a ModR/M byte here?
  2. 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 immediate 2, and so it chooses cl because it is a register?
  3. "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.
  4. Table 2-1 has the value c1 in it, which aligns with the cl register under the "Effective Address" header. Don't know what that means though. The corresponding R/M bit is right there at 001, and the column it's in is 0. 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?

question from:https://stackoverflow.com/questions/65929835/why-does-add-cl-2-print-80-c1-02-in-x86-hex

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
  1. Because the Op/En for the 80 /0 ib says MI which says that Operand1 is in MODRM:r/m.
  2. It means it's only using the "r/m" part of the modr/m and not the "reg" part.
  3. Means the "reg" part contains a constant 0 as an opcode extension.
  4. You look at the modr/m table 2-2, it has a heading row that says "/digit (Opcode)". So you pick the 0 column because of the /0. Then pick the ECX/CX/CL/MM1/XMM1 row and voila, you got your C1 value.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...