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