Exemple #1
0
        public IEnumerable <InstructionInfo> Expand()
        {
            if (this.ModRmByte != ModRmInfo.RegisterPlus)
            {
                yield return(this);

                yield break;
            }

            for (int r = 0; r < 8; r++)
            {
                var subInst = this;
                subInst.ModRmByte = ModRmInfo.None;
                if (!subInst.IsMultiByte)
                {
                    subInst.Opcode += (ushort)r;
                }
                else
                {
                    subInst.Opcode += (ushort)(r << 8);
                }

                int codes = this.Operands.PackedCode & ~(0xFF << (this.RPlusIndex * 8));
                codes |= (int)GetRegisterIndex(r, this.Operands[this.RPlusIndex]) << (this.RPlusIndex * 8);
                if (!operandFormats.TryGetValue(codes, out var operands))
                {
                    operands = new OperandFormat(codes);
                    operandFormats.Add(codes, operands);
                }

                subInst.Operands = operands;

                yield return(subInst);
            }
        }
Exemple #2
0
        public static InstructionInfo Parse(string instructionFormat)
        {
            var info = new InstructionInfo();

            var outer = instructionFormat.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            string[] innerCode;
            if (!outer[0].Contains('+'))
            {
                innerCode = outer[0].Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            }
            else
            {
                innerCode = new string[2] {
                    outer[0].TrimEnd('+'), "+"
                }
            };
            info.Opcode = ushort.Parse(innerCode[0], System.Globalization.NumberStyles.HexNumber);
            if (info.Opcode > 0xFF)
            {
                info.Opcode      = (ushort)(((info.Opcode & 0xFF) << 8) | ((info.Opcode >> 8) & 0xFF));
                info.IsMultiByte = true;
            }

            if (innerCode.Length > 1)
            {
                if (innerCode[1][0] == 'r')
                {
                    info.ModRmByte = ModRmInfo.All;
                }
                else if (innerCode[1][0] == '+')
                {
                    info.ModRmByte = ModRmInfo.RegisterPlus;
                }
                else
                {
                    info.ModRmByte        = ModRmInfo.OnlyRm;
                    info.ExtendedRmOpcode = byte.Parse(new string(innerCode[1][0], 1));
                }
            }

            if (outer.Length > 1)
            {
                string[] innerOperands = outer[1].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                int      operandCode   = 0;

                operandCode = (int)ParseOperand(innerOperands[0]);

                if (innerOperands.Length > 1)
                {
                    operandCode |= (int)ParseOperand(innerOperands[1]) << 8;

                    if (innerOperands.Length > 2)
                    {
                        operandCode |= (int)ParseOperand(innerOperands[2]) << 16;
                    }
                }

                if (!operandFormats.TryGetValue(operandCode, out var format))
                {
                    format = new OperandFormat(operandCode);
                    operandFormats.Add(operandCode, format);
                }

                info.Operands = format;
            }
            else
            {
                if (!operandFormats.TryGetValue(0, out var format))
                {
                    format = new OperandFormat(0);
                    operandFormats.Add(0, format);
                }

                info.Operands = format;
            }

            return(info);
        }