/// <summary> /// Returns a string representation of a memory address. /// </summary> /// <param name="memoryOperand">Memory address operand to be converted to a string.</param> /// <param name="prefixes">Current instruction prefixes in effect.</param> /// <returns>String representation of the memory address.</returns> public static string Format(CodeOperand memoryOperand, PrefixState prefixes) { string prefix = GetSizePrefix(memoryOperand.OperandSize); if (memoryOperand.EffectiveAddress == CodeMemoryBase.SIB) { return(prefix + FormatSib(memoryOperand)); } string register; effectiveAddresses.TryGetValue(memoryOperand.EffectiveAddress, out register); string segmentOverride = FormatSegment(prefixes); if (register == null) { return($"{prefix} {segmentOverride}[{memoryOperand.ImmediateValue:X4}]"); } else if (memoryOperand.ImmediateValue == 0) { return($"{prefix} {segmentOverride}[{register}]"); } else { return($"{prefix} {segmentOverride}[{register}+{memoryOperand.ImmediateValue:X4}]"); } }
bool ISettingParser.TryGetSetting(string name, PrefixState state, out ISettingMetadata setting) { var success = TryGetSetting(name, state, out var temp); setting = temp; return(success); }
private static string FormatSegment(PrefixState prefixes) { switch (prefixes & SegmentOverrideMask) { case PrefixState.CS: return("cs:"); case PrefixState.DS: return("ds:"); case PrefixState.ES: return("es:"); case PrefixState.FS: return("fs:"); case PrefixState.GS: return("gs:"); case PrefixState.SS: return("ss:"); default: return(string.Empty); } }
/// <summary> /// Returns a string representation of a segment register. /// </summary> /// <param name="prefixes">Segment register prefix.</param> /// <returns>String representation of the segment register.</returns> private static string GetSegmentPrefix(PrefixState prefixes) { if ((prefixes & SegmentPrefixes) != 0) { return((prefixes & SegmentPrefixes).ToString().ToLower()); } else { return(null); } }
/// <summary> /// Removes the prefix from the start of the string if it exists. /// </summary> /// <param name="prefix"></param> /// <param name="input"></param> /// <param name="state"></param> /// <returns></returns> public static string Deprefix(string prefix, string input, PrefixState state) { switch (state) { case PrefixState.Required: return(input.CaseInsStartsWith(prefix) ? input.Substring(prefix.Length) : null); case PrefixState.Optional: return(input.CaseInsStartsWith(prefix) ? input.Substring(prefix.Length) : input); case PrefixState.NotPrefixed: return(input); default: throw new InvalidOperationException("Invalid prefix state provided."); } }
/// <summary> /// Attempts to get the setting with the specified name. /// </summary> /// <param name="name"></param> /// <param name="state"></param> /// <param name="setting"></param> /// <returns></returns> public bool TryGetSetting(string name, PrefixState state, out T setting) { bool InternalTryGetSetting(string deprefixedName, out T returned) { var valid = NameMap.TryGetValue(deprefixedName, out var guid); returned = valid ? SettingMap[guid] : default; return(valid); } foreach (var prefix in Prefixes) { var deprefixed = ArgumentMappingUtils.Deprefix(prefix, name, state); if (deprefixed != null && InternalTryGetSetting(deprefixed, out setting)) { return(true); } } setting = default; return(false); }
static void Postfix(ref ZoneSystem __instance, ref bool __result, PrefixState __state) { if (__result) { return; } if (__state.isDungeon) { var locationInstances = AccessTools.FieldRefAccess <ZoneSystem, Dictionary <Vector2i, ZoneSystem.LocationInstance> >(__instance, "m_locationInstances"); foreach (ZoneSystem.LocationInstance locationInstance in locationInstances.Values) { var prefabName = locationInstance.m_location.m_prefabName; if ((IsDungeon(prefabName) || IsTrollCave(prefabName)) && Vector3.Distance(locationInstance.m_position, __state.point) < __state.radius) { __result = true; return; } } } return; }
static void Prefix(string __0, ref string __1, Vector3 __2, ref float __3, out PrefixState __state) { __state = new PrefixState(__2, __3); __state.isDungeon = IsDungeon(__0); }
ISettingMetadata ISettingParser.GetSetting(string name, PrefixState state) => GetSetting(name, state);
/// <summary> /// Gets the setting with the specified name and throws if it's not found. /// </summary> /// <param name="name"></param> /// <param name="state"></param> /// <returns></returns> public T GetSetting(string name, PrefixState state) => TryGetSetting(name, state, out var temp) ? temp : throw new KeyNotFoundException($"There is no setting with the registered name {name}.");
public static DecodedOperands?TryDecode(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes) { try { return(Decode(opcode, rawData, prefixes, out _)); } catch { return(null); } }
public static DecodedOperands Decode(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes) => Decode(opcode, rawData, prefixes, out _);
private static DecodedOperands Decode(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes, out int length) { var reader = new OperandReader(rawData); var operands = new DecodedOperands(); length = 0; if (opcode.Operands.Count == 0) { return(operands); } if (opcode.ModRmInfo != ModRmInfo.None) { byte modRmByte = reader.ReadByte(); int mod = (modRmByte & 0xC0) >> 6; int rm = modRmByte & 0x07; for (int i = 0; i < opcode.Operands.Count; i++) { var type = opcode.Operands[i]; if (type == OperandType.RegisterOrMemoryByte) { operands.SetOperand(i, DecodeRmbw(mod, rm, true, prefixes, ref reader)); } else if (IsPointerOperand(type)) { var operand = DecodeRmbw(mod, rm, false, prefixes, ref reader); if (type == OperandType.EffectiveAddress) { operand.Type = CodeOperandType.EffectiveAddress; } else if (type == OperandType.FullLinearAddress) { operand.Type = CodeOperandType.FullLinearAddress; } else if (type == OperandType.RegisterOrMemoryWordNearPointer) { operand.Type = CodeOperandType.AbsoluteJumpAddress; } else if (type == OperandType.IndirectFarPointer) { operand.Type = CodeOperandType.IndirectFarMemoryAddress; } else if (type == OperandType.MemoryInt16 || type == OperandType.RegisterOrMemory16) { operand.OperandSize = CodeOperandSize.Word; } else if (type == OperandType.MemoryInt32 || type == OperandType.RegisterOrMemory32) { operand.OperandSize = CodeOperandSize.DoubleWord; } else if (type == OperandType.MemoryInt64) { operand.OperandSize = CodeOperandSize.QuadWord; } else if (type == OperandType.MemoryFloat32) { operand.OperandSize = CodeOperandSize.Single; } else if (type == OperandType.MemoryFloat64) { operand.OperandSize = CodeOperandSize.Double; } else if (type == OperandType.MemoryFloat80) { operand.OperandSize = CodeOperandSize.LongDouble; } operands.SetOperand(i, operand); } } if (opcode.ModRmInfo == ModRmInfo.All) { int reg = (modRmByte & 0x38) >> 3; for (int i = 0; i < opcode.Operands.Count; i++) { var type = opcode.Operands[i]; if (type == OperandType.RegisterByte) { operands.SetOperand(i, DecodeRb(reg)); } else if (type == OperandType.RegisterWord) { operands.SetOperand(i, DecodeRw(reg, prefixes)); } else if (type == OperandType.SegmentRegister) { operands.SetOperand(i, DecodeSreg(reg)); } } } } for (int i = 0; i < opcode.Operands.Count; i++) { var type = opcode.Operands[i]; if (IsKnownRegister(type)) { operands.SetOperand(i, new CodeOperand(DecodeKnownRegister(type, (prefixes & PrefixState.OperandSize) != 0))); } else if (type == OperandType.ImmediateByte) { operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, reader.ReadByte(), CodeOperandSize.Byte)); } else if (type == OperandType.ImmediateByteExtend || type == OperandType.ImmediateRelativeByte) { var operand = new CodeOperand(CodeOperandType.Immediate, (uint)(int)reader.ReadSByte(), GetOperandSize(false, prefixes)); if (type == OperandType.ImmediateRelativeByte) { operand.Type = CodeOperandType.RelativeJumpAddress; } operands.SetOperand(i, operand); } else if (type == OperandType.ImmediateInt16) { operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, reader.ReadUInt16(), CodeOperandSize.Word)); } else if (type == OperandType.ImmediateInt32) { operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, reader.ReadUInt32(), CodeOperandSize.DoubleWord)); } else if (type == OperandType.ImmediateWord) { uint value; if ((prefixes & PrefixState.OperandSize) == 0) { value = reader.ReadUInt16(); } else { value = reader.ReadUInt32(); } operands.SetOperand(i, new CodeOperand(CodeOperandType.Immediate, value, GetOperandSize(false, prefixes))); } else if (type == OperandType.ImmediateRelativeWord) { uint value; if ((prefixes & PrefixState.OperandSize) == 0) { value = (uint)(int)reader.ReadInt16(); } else { value = reader.ReadUInt32(); } operands.SetOperand(i, new CodeOperand(CodeOperandType.RelativeJumpAddress, value, GetOperandSize(false, prefixes))); } else if (type == OperandType.MemoryOffsetByte || type == OperandType.MemoryOffsetWord) { uint value; if ((prefixes & PrefixState.AddressSize) == 0) { value = (uint)(int)reader.ReadInt16(); } else { value = reader.ReadUInt32(); } operands.SetOperand(i, new CodeOperand(CodeMemoryBase.DisplacementOnly, value, GetOperandSize(type == OperandType.MemoryOffsetByte, prefixes))); } else if (type == OperandType.ImmediateFarPointer) { uint value; if ((prefixes & PrefixState.AddressSize) == 0) { value = reader.ReadUInt16(); } else { value = reader.ReadUInt32(); } ushort segment = reader.ReadUInt16(); operands.SetOperand(i, CodeOperand.FarPointer(segment, value)); } } length = reader.Position; return(operands); }
public static int CalculateOperandLength(OpcodeInfo opcode, ReadOnlySpan <byte> rawData, PrefixState prefixes) { Decode(opcode, rawData, prefixes, out int length); return(length); }