1

What's the difference in encoding (ModRM:r/m, ModRM:reg) vs (ModRM:reg, ModRM:r/m)? Specifically say an instruction like CMPXCHG vs DIVPD. I thought the register and address was always encoded in the first byte and then the SIB and displacement in the second byte if needed? Here's my code:

    static void WriteRegisterToMemory(ICollection<Byte> bytes, IRegisterToMemoryInstruction instruction, Byte rex)
    {
        IAddress address = instruction.Address;
        Byte register = instruction.Register;

        if (address.NeedsRex)
        {
            rex |= 0x40;
            if (address.RexB)
                rex |= 1;
            if (address.RexX)
                rex |= 1 << 1;
        }

        if (register > 7)
            rex |= 0x44;        // REX.R
        if (rex != 0)
            bytes.Add(rex);

        bytes.AddRange(instruction.Opcode);
        Byte modRM = (Byte)((register % 8) << 3);
        modRM |= address.GetModRMAddressByte();
        bytes.Add(modRM);
        address.WriteScaledIndexByteAndDisplacement(bytes);
    }

So like these two instructions are encoded exactly the same with just different opcodes? (ADDs on page 457 of the intel x64 manual)

Op/En Operand 1        Operand 2 
RM    ModRM:reg (r, w) ModRM:r/m (r) 
MR    ModRM:r/m (r, w) ModRM:reg (r)
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Ryan Brown
  • 1,017
  • 1
  • 13
  • 34
  • 1
    Related: [How to determine if ModR/M is needed through Opcodes?](https://stackoverflow.com/q/55312459) re: Intel's tables of operand encodings. – Peter Cordes Jul 15 '22 at 15:42

1 Answers1

2

There isn't really any difference w.r.t. encoding, the difference is in which one is the source and which one is the destination. Most instructions have the r/m as source, except things like cmpxchg, bts, xadd, xchg is ambiguous about it (it's symmetric), ALU ops have an r/m, r form and an r/m, imm form, and obviously mov's to memory. So in encoding those instructions (even if both operands are registers), be careful "which way around" they are, or they might end up with their operands swapped. But that's all, there is in the end no difference in how they are encoded.

harold
  • 61,398
  • 6
  • 86
  • 164
  • Edited post to ask another question – Ryan Brown Apr 23 '15 at 17:50
  • 1
    @RyanBrown ok I don't really understand what you want to know, what does "encoded the same" mean precisely in this context? Anyway the only difference between `add [eax], edx` and `add edx, [eax]` (assuming 32bit) is the opcode, they both have a ModRM byte of `10` – harold Apr 23 '15 at 18:44
  • I just don't understand why they have both (reg then r/m) and (r/m then reg). They both encode into one byte (usually) so they're not really two seperate operands... – Ryan Brown Apr 23 '15 at 19:03
  • 3
    @RyanBrown but the semantics are not the same, the ModR/M doesn't have an "order of operands" but the instruction does have a notion of "is the `r` the destination or is the `r/m` the destination" – harold Apr 23 '15 at 19:12