/* Copyright (C) 2018-2019 de4dot@gmail.com This file is part of Iced. Iced is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Iced is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Iced. If not, see . */ #if !NO_INSTR_INFO using System.Diagnostics; using System.Text; namespace Iced.Intel { /// /// A memory location used by an instruction /// public readonly struct UsedMemory { readonly ulong displ; readonly byte segReg; readonly byte baseReg; readonly byte indexReg; readonly byte memorySize; readonly byte scale; readonly byte access; /// /// Effective segment register /// public Register Segment => (Register)segReg; /// /// Base register or if none /// public Register Base => (Register)baseReg; /// /// Index register or if none /// public Register Index => (Register)indexReg; /// /// Index scale (1, 2, 4 or 8) /// public int Scale => scale; /// /// Displacement /// public ulong Displacement => displ; /// /// Size of location /// public MemorySize MemorySize => (MemorySize)memorySize; /// /// Memory access /// public OpAccess Access => (OpAccess)access; /// /// Constructor /// /// Segment register /// Base register /// Index register /// Scale, 1, 2, 4 or 8 /// Displacement /// Memory size /// Access public UsedMemory(Register segReg, Register baseReg, Register indexReg, int scale, long displ, MemorySize memorySize, OpAccess access) { this.displ = (ulong)displ; Debug.Assert((uint)segReg <= byte.MaxValue); this.segReg = (byte)segReg; Debug.Assert((uint)baseReg <= byte.MaxValue); this.baseReg = (byte)baseReg; Debug.Assert((uint)indexReg <= byte.MaxValue); this.indexReg = (byte)indexReg; Debug.Assert((uint)memorySize <= byte.MaxValue); this.memorySize = (byte)memorySize; Debug.Assert(scale == 1 || scale == 2 || scale == 4 || scale == 8); this.scale = (byte)scale; Debug.Assert((uint)access <= byte.MaxValue); this.access = (byte)access; } /// /// Constructor /// /// Segment register /// Base register /// Index register /// Scale, 1, 2, 4 or 8 /// Displacement /// Memory size /// Access public UsedMemory(Register segReg, Register baseReg, Register indexReg, int scale, ulong displ, MemorySize memorySize, OpAccess access) { this.displ = displ; Debug.Assert((uint)segReg <= byte.MaxValue); this.segReg = (byte)segReg; Debug.Assert((uint)baseReg <= byte.MaxValue); this.baseReg = (byte)baseReg; Debug.Assert((uint)indexReg <= byte.MaxValue); this.indexReg = (byte)indexReg; Debug.Assert((uint)memorySize <= byte.MaxValue); this.memorySize = (byte)memorySize; Debug.Assert(scale == 1 || scale == 2 || scale == 4 || scale == 8); this.scale = (byte)scale; Debug.Assert((uint)access <= byte.MaxValue); this.access = (byte)access; } /// /// ToString() /// /// public override string ToString() { var sb = new StringBuilder(); sb.Append('['); sb.Append(Segment.ToString()); sb.Append(':'); bool needPlus = false; if (Base != Register.None) { sb.Append(Base.ToString()); needPlus = true; } if (Index != Register.None) { if (needPlus) sb.Append('+'); needPlus = true; sb.Append(Index.ToString()); if (Scale != 1) { sb.Append('*'); sb.Append((char)('0' + Scale)); } } if (Displacement != 0 || !needPlus) { if (needPlus) sb.Append('+'); if (Displacement <= 9) sb.Append(Displacement.ToString()); else { sb.Append("0x"); sb.Append(Displacement.ToString("X")); } } sb.Append(';'); sb.Append(MemorySize.ToString()); sb.Append(';'); sb.Append(Access.ToString()); sb.Append(']'); return sb.ToString(); } } } #endif