diff --git a/X86Disassembler/X86/ModRMDecoder.cs b/X86Disassembler/X86/ModRMDecoder.cs
index c481bd9..e82b159 100644
--- a/X86Disassembler/X86/ModRMDecoder.cs
+++ b/X86Disassembler/X86/ModRMDecoder.cs
@@ -8,27 +8,27 @@ public class ModRMDecoder
// ModR/M byte masks
private const byte MOD_MASK = 0xC0; // 11000000b
private const byte REG_MASK = 0x38; // 00111000b
- private const byte RM_MASK = 0x07; // 00000111b
-
+ private const byte RM_MASK = 0x07; // 00000111b
+
// SIB byte masks
private const byte SIB_SCALE_MASK = 0xC0; // 11000000b
private const byte SIB_INDEX_MASK = 0x38; // 00111000b
- private const byte SIB_BASE_MASK = 0x07; // 00000111b
-
+ private const byte SIB_BASE_MASK = 0x07; // 00000111b
+
// Register names for different sizes
- private static readonly string[] RegisterNames8 = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
- private static readonly string[] RegisterNames16 = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
- private static readonly string[] RegisterNames32 = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };
+ private static readonly string[] RegisterNames8 = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
+ private static readonly string[] RegisterNames16 = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
+ private static readonly string[] RegisterNames32 = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
// Buffer containing the code to decode
private readonly byte[] _codeBuffer;
-
+
// The instruction decoder that owns this ModRM decoder
private readonly InstructionDecoder _decoder;
-
+
// Length of the buffer
private readonly int _length;
-
+
///
/// Initializes a new instance of the ModRMDecoder class
///
@@ -41,7 +41,7 @@ public class ModRMDecoder
_decoder = decoder;
_length = length;
}
-
+
///
/// Decodes a ModR/M byte to get the operand string
///
@@ -51,113 +51,116 @@ public class ModRMDecoder
/// The operand string
public string DecodeModRM(byte mod, RegisterIndex rmIndex, bool is64Bit)
{
- string sizePrefix = is64Bit ? "qword" : "dword";
- int position = _decoder.GetPosition();
-
+ string sizePrefix = is64Bit
+ ? "qword"
+ : "dword";
+
switch (mod)
{
case 0: // [reg] or disp32
// Special case: [EBP] is encoded as disp32 with no base register
if (rmIndex == RegisterIndex.Di) // disp32 (was EBP/BP)
{
- if (position + 4 <= _length)
+ if (_decoder.CanReadUInt())
{
- uint disp32 = BitConverter.ToUInt32(_codeBuffer, position);
- _decoder.SetPosition(position + 4);
+ uint disp32 = _decoder.ReadUInt32();
return $"{sizePrefix} ptr [0x{disp32:X8}]";
}
+
return $"{sizePrefix} ptr [???]";
}
+
// Special case: [ESP] is encoded with SIB byte
- else if (rmIndex == RegisterIndex.Si) // SIB (was ESP/SP)
+ if (rmIndex == RegisterIndex.Si) // SIB (was ESP/SP)
{
// Handle SIB byte
- if (position < _length)
+ if (_decoder.CanReadByte())
{
- byte sib = _codeBuffer[position];
- _decoder.SetPosition(position + 1);
+ byte sib = _decoder.ReadByte();
return DecodeSIB(sib, 0, is64Bit);
}
+
return $"{sizePrefix} ptr [???]";
}
- else
- {
- // Regular case: [reg]
- return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
- }
-
+
+ // Regular case: [reg]
+ return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
+
case 1: // [reg + disp8]
if (rmIndex == RegisterIndex.Si) // SIB + disp8 (was ESP/SP)
{
// Handle SIB byte
- if (position + 1 < _length)
+ if (_decoder.CanReadByte())
{
- byte sib = _codeBuffer[position];
- sbyte disp8 = (sbyte)_codeBuffer[position + 1];
- _decoder.SetPosition(position + 2);
+ byte sib = _decoder.ReadByte();
+ uint disp8 = (uint) (sbyte) _decoder.ReadByte();
return DecodeSIB(sib, disp8, is64Bit);
}
+
return $"{sizePrefix} ptr [???]";
}
else
{
- if (position < _length)
+ if (_decoder.CanReadByte())
{
- sbyte disp8 = (sbyte)_codeBuffer[position];
- _decoder.SetPosition(position + 1);
-
+ sbyte disp8 = (sbyte) _decoder.ReadByte();
+
// Only show displacement if it's not zero
if (disp8 == 0)
{
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
}
-
- string dispStr8 = disp8 < 0 ? $"-0x{-disp8:X2}" : $"+0x{disp8:X2}";
+
+ string dispStr8 = disp8 < 0
+ ? $"-0x{-disp8:X2}"
+ : $"+0x{disp8:X2}";
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}{dispStr8}]";
}
+
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
}
-
+
case 2: // [reg + disp32]
if (rmIndex == RegisterIndex.Si) // SIB + disp32 (was ESP/SP)
{
// Handle SIB byte
- if (position + 4 < _length)
+ if (_decoder.CanReadUInt())
{
- byte sib = _codeBuffer[position];
- int disp32 = BitConverter.ToInt32(_codeBuffer, position + 1);
- _decoder.SetPosition(position + 5);
+ byte sib = _decoder.ReadByte();
+ uint disp32 = _decoder.ReadUInt32();
return DecodeSIB(sib, disp32, is64Bit);
}
+
return $"{sizePrefix} ptr [???]";
}
else
{
- if (position + 4 <= _length)
+ if (_decoder.CanReadUInt())
{
- int disp32 = BitConverter.ToInt32(_codeBuffer, position);
- _decoder.SetPosition(position + 4);
-
+ uint disp32 = _decoder.ReadUInt32();
+
// Only show displacement if it's not zero
if (disp32 == 0)
{
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}]";
}
-
- string dispStr32 = disp32 < 0 ? $"-0x{-disp32:X8}" : $"+0x{disp32:X8}";
- return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}{dispStr32}]";
+
+ return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+0x{disp32:X8}]";
}
+
return $"{sizePrefix} ptr [{GetRegisterName(rmIndex, 32)}+???]";
}
-
+
case 3: // reg (direct register access)
- return is64Bit ? $"mm{(int)rmIndex}" : GetRegisterName(rmIndex, 32);
-
+ return is64Bit
+ ? $"mm{(int) rmIndex}"
+ : GetRegisterName(rmIndex, 32);
+
default:
return "???";
}
}
-
+
///
/// Reads and decodes a ModR/M byte
///
@@ -165,26 +168,23 @@ public class ModRMDecoder
/// A tuple containing the mod, reg, rm fields and the decoded operand string
public (byte mod, RegisterIndex reg, RegisterIndex rm, string operand) ReadModRM(bool is64Bit = false)
{
- int position = _decoder.GetPosition();
-
- if (position >= _length)
+ if (!_decoder.CanReadByte())
{
return (0, RegisterIndex.A, RegisterIndex.A, "???");
}
-
- byte modRM = _codeBuffer[position];
- _decoder.SetPosition(position + 1);
-
+
+ byte modRM = _decoder.ReadByte();
+
// Extract fields from ModR/M byte
- byte mod = (byte)((modRM & MOD_MASK) >> 6);
- RegisterIndex reg = (RegisterIndex)((modRM & REG_MASK) >> 3);
- RegisterIndex rm = (RegisterIndex)(modRM & RM_MASK);
-
+ byte mod = (byte) ((modRM & MOD_MASK) >> 6);
+ RegisterIndex reg = (RegisterIndex) ((modRM & REG_MASK) >> 3);
+ RegisterIndex rm = (RegisterIndex) (modRM & RM_MASK);
+
string operand = DecodeModRM(mod, rm, is64Bit);
-
+
return (mod, reg, rm, operand);
}
-
+
///
/// Decodes a SIB byte
///
@@ -192,63 +192,57 @@ public class ModRMDecoder
/// The displacement value
/// True if the operand is 64-bit
/// The decoded SIB string
- private string DecodeSIB(byte sib, int displacement, bool is64Bit)
+ private string DecodeSIB(byte sib, uint displacement, bool is64Bit)
{
- string sizePrefix = is64Bit ? "qword" : "dword";
- int position = _decoder.GetPosition();
-
+ string sizePrefix = is64Bit
+ ? "qword"
+ : "dword";
+
// Extract fields from SIB byte
- byte scale = (byte)((sib & SIB_SCALE_MASK) >> 6);
- RegisterIndex index = (RegisterIndex)((sib & SIB_INDEX_MASK) >> 3);
- RegisterIndex @base = (RegisterIndex)(sib & SIB_BASE_MASK);
-
+ byte scale = (byte) ((sib & SIB_SCALE_MASK) >> 6);
+ RegisterIndex index = (RegisterIndex) ((sib & SIB_INDEX_MASK) >> 3);
+ RegisterIndex @base = (RegisterIndex) (sib & SIB_BASE_MASK);
+
// Special case: ESP/SP (4) in index field means no index register
if (index == RegisterIndex.Si)
{
// Special case: EBP/BP (5) in base field with no displacement means disp32 only
if (@base == RegisterIndex.Di && displacement == 0)
{
- if (position + 4 <= _length)
+ if (_decoder.CanReadUInt())
{
- uint disp32 = BitConverter.ToUInt32(_codeBuffer, position);
- _decoder.SetPosition(position + 4);
+ uint disp32 = _decoder.ReadUInt32();
return $"{sizePrefix} ptr [0x{disp32:X8}]";
}
+
return $"{sizePrefix} ptr [???]";
}
- else
+
+ // Base register only
+ // Only show displacement if it's not zero
+ if (displacement == 0)
{
- // Base register only
- // Only show displacement if it's not zero
- if (displacement == 0)
- {
- return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}]";
- }
-
- string baseDispStr = displacement < 0 ?
- $"-0x{-displacement:X}" :
- $"+0x{displacement:X}";
- return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}{baseDispStr}]";
+ return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}]";
}
+
+ return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+0x{displacement:X}]";
}
-
+
// Normal case with base and index registers
int scaleFactor = 1 << scale; // 1, 2, 4, or 8
-
+
// Only include the scale factor if it's not 1
- string scaleStr = scaleFactor > 1 ? $"*{scaleFactor}" : "";
-
+ string scaleStr = scaleFactor > 1
+ ? $"*{scaleFactor}"
+ : "";
+
// Only show displacement if it's not zero
if (displacement == 0)
{
return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}]";
}
-
- string indexDispStr = displacement < 0 ?
- $"-0x{-displacement:X}" :
- $"+0x{displacement:X}";
-
- return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}{indexDispStr}]";
+
+ return $"{sizePrefix} ptr [{GetRegisterName(@base, 32)}+{GetRegisterName(index, 32)}{scaleStr}+0x{displacement:X}]";
}
///
@@ -260,8 +254,8 @@ public class ModRMDecoder
public static string GetRegisterName(RegisterIndex regIndex, int size)
{
// Convert RegisterIndex to raw index for array access
- int index = (int)regIndex;
-
+ int index = (int) regIndex;
+
return size switch
{
8 => RegisterNames8[index],
@@ -270,4 +264,4 @@ public class ModRMDecoder
_ => RegisterNames32[index] // Default to 32-bit registers
};
}
-}
+}
\ No newline at end of file