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);
            }
            }
        }
Beispiel #2
0
        ///  <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);
        }
Beispiel #3
0
        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);
        }