private static bool OperandMatches(OperandDefinition opDef, Operand op) { if (op.Size != opDef.Size) { return(false); } switch (opDef) { case FixedOperandDefinition fixDef: { return(op is RegisterOperand reg && reg.Name == fixDef.Name); } default: { // if we have a register operand but the definition requires a memory operand that is a match still if (op.Type == opDef.Type) { return(true); } return(op.Type == OperandType.Register && opDef.Type == OperandType.Memory); } } }
/// <summary> /// /// </summary> /// <param name="operand1">Memory operand</param> /// <param name="op1Def"></param> /// <param name="operand2">reg operand</param> /// <param name="op2Def"></param> /// <returns></returns> private static byte?CalculateModRM(Operand operand1, OperandDefinition op1Def, Operand operand2, OperandDefinition op2Def) { var reg1Bits = CalculateModRMRegBits(operand1, op1Def); if (reg1Bits != null) { var reg1Byte = reg1Bits.Value; var reg2Bits = CalculateModRMRegBits(operand2, op2Def); var mod = CalculateModRmModBits(operand1, reg1Bits) << 6; if (reg2Bits != null) { var reg2Byte = reg2Bits.Value; return((byte)(mod | (reg2Byte << 3) | reg1Byte)); } return((byte)(mod | reg1Byte)); } return(null); }
private static byte?CalculateModRMRegBits(Operand op, OperandDefinition opDef) { if (op is RegisterOperand rmReg && opDef.Type != OperandType.Fixed) { return((byte)(RegisterByte(rmReg.Name) & 0b111)); } if (op is MemoryOperand mem1) { if (mem1.InnerOperand is RegisterOperand reg) { return((byte)(RegisterByte(reg.Name) & 0b111)); } if (mem1.InnerOperand is ImmOperand) { return(0b100); // SP } } return(null); }