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