x64指令编码(r / m,reg vs reg,r / m)

时间:2015-04-23 01:06:43

标签: 64-bit machine-code

编码有什么区别(ModRM:r / m,ModRM:reg)vs(ModRM:reg,ModRM:r / m)?具体来说就像CMPXCHG和DIVPD这样的指令。我认为寄存器和地址总是在第一个字节中编码,然后在需要时在第二个字节中进行SIB和位移?这是我的代码:

    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);
    }

那么这两个指令的编码方式完全相同,只是不同的操作码? (英特尔x64手册第457页的ADD)

Op/En Operand 1        Operand 2 
RM    ModRM:reg (r, w) ModRM:r/m (r) 
MR    ModRM:r/m (r, w) ModRM:reg (r)

1 个答案:

答案 0 :(得分:1)

w.r.t没有任何区别。编码,区别在于哪一个是源,哪一个是目的地。大多数说明都以r/m作为来源,但cmpxchgbtsxaddxchg之类的内容不明确(它是对称的) ,ALU ops有一个r/m, r形式和一个r/m, imm形式,显然是对记忆的影响。因此,在对这些指令进行编码时(即使两个操作数都是寄存器),请注意&#34;哪种方式&#34;他们是,或者他们可能最终交换他们的操作数。但总而言之,最终编码方式没有区别。