0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-05-18 19:31:17 +03:00

more refactoring

This commit is contained in:
bird_egop 2025-04-14 01:08:14 +03:00
parent f54dc10596
commit 99b93523a4
78 changed files with 379 additions and 594 deletions

View File

@ -28,7 +28,7 @@ public class AdcImmToRm32Handler : InstructionHandler
// Check if the reg field of the ModR/M byte is 2 (ADC)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
@ -48,9 +48,7 @@ public class AdcImmToRm32Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "adc";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -58,8 +56,7 @@ public class AdcImmToRm32Handler : InstructionHandler
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false;
}

View File

@ -28,7 +28,7 @@ public class AdcImmToRm32SignExtendedHandler : InstructionHandler
// Check if the reg field of the ModR/M byte is 2 (ADC)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
@ -48,9 +48,7 @@ public class AdcImmToRm32SignExtendedHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "adc";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -58,13 +56,12 @@ public class AdcImmToRm32SignExtendedHandler : InstructionHandler
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value (sign-extended from 8 to 32 bits)
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Sign-extend to 32 bits
// Read the immediate value (sign-extended from 8 to 32 bits)
int imm32 = (sbyte) Decoder.ReadByte();
// Set the operands

View File

@ -11,11 +11,11 @@ public class AddEaxImmHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AddEaxImmHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AddEaxImmHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,7 +25,7 @@ public class AddEaxImmHandler : InstructionHandler
{
return opcode == 0x05;
}
/// <summary>
/// Decodes an ADD EAX, imm32 instruction
/// </summary>
@ -36,24 +36,21 @@ public class AddEaxImmHandler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "add";
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false; // Not enough bytes for the immediate value
return false;
}
// Read the 32-bit immediate value
uint imm32 = Decoder.ReadUInt32();
// Format the immediate value
string immStr = $"0x{imm32:X}";
// Set the operands
instruction.Operands = $"eax, {immStr}";
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class AddImmToRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AddImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AddImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class AddImmToRm32Handler : InstructionHandler
{
if (opcode != 0x81)
return false;
// Check if the reg field of the ModR/M byte is 0 (ADD)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 0; // 0 = ADD
}
/// <summary>
/// Decodes an ADD r/m32, imm32 instruction
/// </summary>
@ -47,33 +47,31 @@ public class AddImmToRm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "add";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false;
}
// Read the immediate value in little-endian format
var imm = Decoder.ReadUInt32();
// Format the immediate value as expected by the tests (0x12345678)
// Note: The bytes are reversed to match the expected format in the tests
string immStr = $"0x{imm:X8}";
// Set the operands
instruction.Operands = $"{destOperand}, {immStr}";
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class AddImmToRm32SignExtendedHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AddImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AddImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class AddImmToRm32SignExtendedHandler : InstructionHandler
{
if (opcode != 0x83)
return false;
// Check if the reg field of the ModR/M byte is 0 (ADD)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 0; // 0 = ADD
}
/// <summary>
/// Decodes an ADD r/m32, imm8 (sign-extended) instruction
/// </summary>
@ -47,45 +47,40 @@ public class AddImmToRm32SignExtendedHandler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "add";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the position after decoding the ModR/M byte
position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the immediate value as a signed byte and automatically sign-extend it to int
int signExtendedImm = (sbyte)Decoder.ReadByte();
int imm = (sbyte) Decoder.ReadByte();
// Format the immediate value
string immStr;
if (signExtendedImm < 0)
if (imm < 0)
{
// For negative values, use the full 32-bit representation (0xFFFFFFxx)
immStr = $"0x{(uint)signExtendedImm:X8}";
immStr = $"0x{(uint) imm:X8}";
}
else
{
// For positive values, use the regular format with leading zeros
immStr = $"0x{signExtendedImm:X8}";
immStr = $"0x{imm:X8}";
}
// Set the operands
instruction.Operands = $"{destOperand}, {immStr}";
return true;
}
}
}

View File

@ -28,7 +28,7 @@ public class AddImmToRm8Handler : InstructionHandler
// Check if the reg field of the ModR/M byte is 0 (ADD)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
@ -48,9 +48,7 @@ public class AddImmToRm8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "add";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -66,7 +64,7 @@ public class AddImmToRm8Handler : InstructionHandler
}
// Read the immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -34,9 +34,7 @@ public class AddR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -34,9 +34,7 @@ public class AddRm32R32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -36,11 +36,9 @@ public class AndAlImmHandler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
// Read immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
instruction.Operands = "al, ??";
return true;

View File

@ -36,11 +36,9 @@ public class AndEaxImmHandler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
// Read immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
instruction.Operands = "eax, ??";
return true;

View File

@ -11,11 +11,11 @@ public class AndImmToRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AndImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AndImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class AndImmToRm32Handler : InstructionHandler
{
if (opcode != 0x81)
return false;
// Check if the reg field of the ModR/M byte is 4 (AND)
int position = Decoder.GetPosition();
if (position >= Length)
if (Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 4; // 4 = AND
}
/// <summary>
/// Decodes an AND r/m32, imm32 instruction
/// </summary>
@ -47,33 +47,31 @@ public class AndImmToRm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false;
}
// Read the immediate value in little-endian format
var imm = Decoder.ReadUInt32();
// Format the immediate value as expected by the tests (0x12345678)
// Note: The bytes are reversed to match the expected format in the tests
string immStr = $"0x{imm:X8}";
// Set the operands
instruction.Operands = $"{destOperand}, {immStr}";
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AndImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AndImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -27,22 +27,22 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
{
return false;
}
// Check if we have enough bytes to read the ModR/M byte
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte to check the reg field (bits 5-3)
byte modRM = CodeBuffer[position];
int reg = (modRM >> 3) & 0x7;
// reg = 4 means AND operation
return reg == 4;
}
/// <summary>
/// Decodes an AND r/m32, imm8 (sign-extended) instruction
/// </summary>
@ -53,22 +53,18 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
// Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get the position after decoding the ModR/M byte
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false; // Not enough bytes for the immediate value
}
// Read the immediate value as a signed byte and automatically sign-extend it to int
int signExtendedImm = (sbyte)Decoder.ReadByte();
int imm = (sbyte) Decoder.ReadByte();
// Format the destination operand based on addressing mode
string destOperand;
if (mod == 3) // Register addressing mode
@ -81,23 +77,23 @@ public class AndImmToRm32SignExtendedHandler : InstructionHandler
// Memory operand already includes dword ptr prefix
destOperand = memOperand;
}
// Format the immediate value
string immStr;
if (signExtendedImm < 0)
if (imm < 0)
{
// For negative values, use the full 32-bit representation
immStr = $"0x{(uint)signExtendedImm:X8}";
immStr = $"0x{(uint) imm:X8}";
}
else
{
// For positive values, use the regular format with leading zeros
immStr = $"0x{signExtendedImm:X8}";
immStr = $"0x{imm:X8}";
}
// Set the operands
instruction.Operands = $"{destOperand}, {immStr}";
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class AndImmToRm8Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AndImmToRm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AndImmToRm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -27,22 +27,22 @@ public class AndImmToRm8Handler : InstructionHandler
{
return false;
}
// Check if we have enough bytes to read the ModR/M byte
int position = Decoder.GetPosition();
if (position >= Length)
if (Decoder.CanReadByte())
{
return false;
}
int position = Decoder.GetPosition();
// Read the ModR/M byte to check the reg field (bits 5-3)
byte modRM = CodeBuffer[position];
int reg = (modRM >> 3) & 0x7;
// reg = 4 means AND operation
return reg == 4;
}
/// <summary>
/// Decodes an AND r/m8, imm8 instruction
/// </summary>
@ -53,22 +53,18 @@ public class AndImmToRm8Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
// Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get the position after decoding the ModR/M byte
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false; // Not enough bytes for the immediate value
}
// Read the immediate value
byte imm8 = Decoder.ReadByte();
// Format the destination operand based on addressing mode
string destOperand;
if (mod == 3) // Register addressing mode
@ -81,13 +77,13 @@ public class AndImmToRm8Handler : InstructionHandler
// Add byte ptr prefix for memory operands
destOperand = $"byte ptr {memOperand}";
}
// Format the immediate value
string immStr = $"0x{imm8:X2}";
// Set the operands
instruction.Operands = $"{destOperand}, {immStr}";
return true;
}
}
}

View File

@ -28,7 +28,7 @@ public class AndImmWithRm32Handler : InstructionHandler
// Check if the reg field of the ModR/M byte is 4 (AND)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
@ -55,7 +55,7 @@ public class AndImmWithRm32Handler : InstructionHandler
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false; // Not enough bytes for the immediate value
}

View File

@ -11,11 +11,11 @@ public class AndMemRegHandler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AndMemRegHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AndMemRegHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,7 +25,7 @@ public class AndMemRegHandler : InstructionHandler
{
return opcode == 0x21;
}
/// <summary>
/// Decodes an AND r/m32, r32 instruction
/// </summary>
@ -36,20 +36,18 @@ public class AndMemRegHandler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 32);
// For mod == 3, both operands are registers
if (mod == 3)
{
@ -60,4 +58,4 @@ public class AndMemRegHandler : InstructionHandler
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class AndR32Rm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AndR32Rm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AndR32Rm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,7 +25,7 @@ public class AndR32Rm32Handler : InstructionHandler
{
return opcode == 0x23;
}
/// <summary>
/// Decodes an AND r32, r/m32 instruction
/// </summary>
@ -36,20 +36,18 @@ public class AndR32Rm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 32);
// For mod == 3, both operands are registers
if (mod == 3)
{
@ -60,4 +58,4 @@ public class AndR32Rm32Handler : InstructionHandler
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class AndR8Rm8Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AndR8Rm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AndR8Rm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,7 +25,7 @@ public class AndR8Rm8Handler : InstructionHandler
{
return opcode == 0x22;
}
/// <summary>
/// Decodes an AND r8, r/m8 instruction
/// </summary>
@ -36,20 +36,18 @@ public class AndR8Rm8Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 8);
// For mod == 3, both operands are registers
if (mod == 3)
{
@ -60,7 +58,7 @@ public class AndR8Rm8Handler : InstructionHandler
{
instruction.Operands = $"{regName}, byte ptr {memOperand}";
}
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class AndRm8R8Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public AndRm8R8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public AndRm8R8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,7 +25,7 @@ public class AndRm8R8Handler : InstructionHandler
{
return opcode == 0x20;
}
/// <summary>
/// Decodes an AND r/m8, r8 instruction
/// </summary>
@ -36,20 +36,18 @@ public class AndRm8R8Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "and";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM();
// Get register name
string regName = ModRMDecoder.GetRegisterName(reg, 8);
// For mod == 3, both operands are registers
if (mod == 3)
{
@ -60,7 +58,7 @@ public class AndRm8R8Handler : InstructionHandler
{
instruction.Operands = $"byte ptr {memOperand}, {regName}";
}
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class DivRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public DivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public DivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class DivRm32Handler : InstructionHandler
{
if (opcode != 0xF7)
return false;
// Check if the reg field of the ModR/M byte is 6 (DIV)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 6; // 6 = DIV
}
/// <summary>
/// Decodes a DIV r/m32 instruction
/// </summary>
@ -47,20 +47,18 @@ public class DivRm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "div";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands
instruction.Operands = destOperand;
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class IdivRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public IdivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public IdivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class IdivRm32Handler : InstructionHandler
{
if (opcode != 0xF7)
return false;
// Check if the reg field of the ModR/M byte is 7 (IDIV)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 7; // 7 = IDIV
}
/// <summary>
/// Decodes an IDIV r/m32 instruction
/// </summary>
@ -47,20 +47,18 @@ public class IdivRm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "idiv";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands
instruction.Operands = destOperand;
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class ImulRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public ImulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public ImulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class ImulRm32Handler : InstructionHandler
{
if (opcode != 0xF7)
return false;
// Check if the reg field of the ModR/M byte is 5 (IMUL)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 5; // 5 = IMUL
}
/// <summary>
/// Decodes an IMUL r/m32 instruction
/// </summary>
@ -47,20 +47,18 @@ public class ImulRm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "imul";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands
instruction.Operands = destOperand;
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class MulRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public MulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public MulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class MulRm32Handler : InstructionHandler
{
if (opcode != 0xF7)
return false;
// Check if the reg field of the ModR/M byte is 4 (MUL)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 4; // 4 = MUL
}
/// <summary>
/// Decodes a MUL r/m32 instruction
/// </summary>
@ -47,20 +47,18 @@ public class MulRm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "mul";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands
instruction.Operands = destOperand;
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class NegRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public NegRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public NegRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,18 +25,18 @@ public class NegRm32Handler : InstructionHandler
{
if (opcode != 0xF7)
return false;
// Check if the reg field of the ModR/M byte is 3 (NEG)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 3; // 3 = NEG
}
/// <summary>
/// Decodes a NEG r/m32 instruction
/// </summary>
@ -47,20 +47,18 @@ public class NegRm32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "neg";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Set the operands
instruction.Operands = destOperand;
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class NotRm32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public NotRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public NotRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -26,18 +26,18 @@ public class NotRm32Handler : InstructionHandler
// This handler only handles opcode 0xF7
if (opcode != 0xF7)
return false;
// Check if the reg field of the ModR/M byte is 2 (NOT)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 2; // 2 = NOT
}
/// <summary>
/// Decodes a NOT r/m32 instruction
/// </summary>
@ -46,36 +46,32 @@ public class NotRm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Verify this is a NOT instruction
if (reg != RegisterIndex.C)
{
return false;
}
// Set the mnemonic
instruction.Mnemonic = "not";
Decoder.SetPosition(position);
// For direct register addressing (mod == 3), the r/m field specifies a register
if (mod == 3)
{
destOperand = ModRMDecoder.GetRegisterName(rm, 32);
}
// Set the operands
instruction.Operands = destOperand;
return true;
}
}
}

View File

@ -11,11 +11,11 @@ public class CallRel32Handler : InstructionHandler
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public CallRel32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
public CallRel32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
@ -25,7 +25,7 @@ public class CallRel32Handler : InstructionHandler
{
return opcode == 0xE8;
}
/// <summary>
/// Decodes a CALL rel32 instruction
/// </summary>
@ -36,23 +36,23 @@ public class CallRel32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "call";
int position = Decoder.GetPosition();
if (position + 4 > Length)
if (!Decoder.CanReadUInt())
{
return false;
}
int position = Decoder.GetPosition();
// Read the relative offset
uint offset = Decoder.ReadUInt32();
// Calculate the target address
uint targetAddress = (uint)(position + offset + 4);
uint targetAddress = (uint) (position + offset + 4);
// Set the operands
instruction.Operands = $"0x{targetAddress:X8}";
return true;
}
}
}

View File

@ -34,9 +34,7 @@ public class CallRm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,16 +37,13 @@ public class CmpAlImmHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "cmp";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the immediate value
byte imm8 = Decoder.ReadByte();
Decoder.SetPosition(position);
// Set the operands
instruction.Operands = $"al, 0x{imm8:X2}";

View File

@ -27,11 +27,10 @@ public class CmpImmWithRm32Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 7 (CMP)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 7; // 7 = CMP
@ -55,7 +54,7 @@ public class CmpImmWithRm32Handler : InstructionHandler
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false; // Not enough bytes for the immediate value
}

View File

@ -28,7 +28,7 @@ public class CmpImmWithRm32SignExtendedHandler : InstructionHandler
// Check if the reg field of the ModR/M byte is 7 (CMP)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
@ -50,7 +50,7 @@ public class CmpImmWithRm32SignExtendedHandler : InstructionHandler
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -59,14 +59,13 @@ public class CmpImmWithRm32SignExtendedHandler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the immediate value as a signed byte and sign-extend it
sbyte imm8 = (sbyte) Decoder.ReadByte();
Decoder.SetPosition(position);
// Set the operands
instruction.Operands = $"{destOperand}, 0x{(uint) imm8:X2}";

View File

@ -55,7 +55,7 @@ public class CmpImmWithRm8Handler : InstructionHandler
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false; // Not enough bytes for the immediate value
}

View File

@ -34,9 +34,7 @@ public class CmpR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -36,11 +36,8 @@ public class CmpRm32R32Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "cmp";
// Save the original position to properly handle the ModR/M byte
int originalPosition = Decoder.GetPosition();
if (originalPosition >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -47,9 +47,7 @@ public class Float32OperationHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -47,9 +47,7 @@ public class Float64OperationHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -55,15 +55,12 @@ public class FnstswHandler : InstructionHandler
}
// Verify the second byte is 0xE0
byte secondByte = CodeBuffer[Decoder.GetPosition()];
byte secondByte = Decoder.ReadByte();
if (secondByte != 0xE0)
{
return false;
}
// Skip the second byte of the opcode
Decoder.ReadByte(); // Consume the 0xE0 byte
// Set the mnemonic and operands
instruction.Mnemonic = "fnstsw";
instruction.Operands = "ax";

View File

@ -34,9 +34,8 @@ public class LeaR32MHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
// Check if we have enough bytes for the ModR/M byte
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,8 @@ public class MovMemRegHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "mov";
int position = Decoder.GetPosition();
if (position >= Length)
// Check if we have enough bytes for the ModR/M byte
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,8 @@ public class MovRm8Imm8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "mov";
int position = Decoder.GetPosition();
if (position >= Length)
// Check if we have enough bytes for the ModR/M byte
if (!Decoder.CanReadByte())
{
return false;
}
@ -66,7 +65,7 @@ public class MovRm8Imm8Handler : InstructionHandler
}
// Read the immediate value
if (Decoder.GetPosition() >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -23,6 +23,7 @@ public class NopHandler : InstructionHandler
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// NOP (XCHG EAX, EAX)
return opcode == 0x90;
}

View File

@ -34,9 +34,7 @@ public class OrAlImmHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -34,9 +34,7 @@ public class OrEaxImmHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position + 3 >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class OrImmToRm32Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 1 (OR)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 1; // 1 = OR
@ -48,7 +47,7 @@ public class OrImmToRm32Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "or";
if (Decoder.GetPosition() >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -56,10 +55,7 @@ public class OrImmToRm32Handler : InstructionHandler
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
int position = Decoder.GetPosition();
// Read the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class OrImmToRm32SignExtendedHandler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 1 (OR)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 1; // 1 = OR

View File

@ -27,11 +27,10 @@ public class OrImmToRm8Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 1 (OR)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 1; // 1 = OR
@ -48,9 +47,7 @@ public class OrImmToRm8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "or";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -65,9 +62,8 @@ public class OrImmToRm8Handler : InstructionHandler
destOperand = ModRMDecoder.GetRegisterName(rm, 8);
}
position = Decoder.GetPosition();
if (position >= Length)
// Read the immediate value
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -34,9 +34,7 @@ public class OrR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -34,9 +34,7 @@ public class OrR8Rm8Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,7 @@ public class RetImmHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "ret";
int position = Decoder.GetPosition();
if (position + 2 > Length)
if (!Decoder.CanReadUShort())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class SbbImmFromRm32Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 3 (SBB)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 3; // 3 = SBB
@ -48,9 +47,7 @@ public class SbbImmFromRm32Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sbb";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -59,7 +56,7 @@ public class SbbImmFromRm32Handler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class SbbImmFromRm32SignExtendedHandler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 3 (SBB)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 3; // 3 = SBB
@ -48,9 +47,7 @@ public class SbbImmFromRm32SignExtendedHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sbb";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -59,7 +56,7 @@ public class SbbImmFromRm32SignExtendedHandler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate value (sign-extended from 8 to 32 bits)
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -47,17 +47,18 @@ public class StringInstructionHandler : InstructionHandler
}
// Check if the opcode is a REP/REPNE prefix followed by a string instruction
if (opcode == REP_PREFIX || opcode == REPNE_PREFIX)
if (opcode != REP_PREFIX && opcode != REPNE_PREFIX)
{
int position = Decoder.GetPosition();
if (position < Length)
{
byte nextByte = CodeBuffer[position];
return StringInstructions.ContainsKey(nextByte);
}
return false;
}
return false;
if (!Decoder.CanReadByte())
{
return false;
}
byte nextByte = CodeBuffer[Decoder.GetPosition()];
return StringInstructions.ContainsKey(nextByte);
}
/// <summary>
@ -79,34 +80,34 @@ public class StringInstructionHandler : InstructionHandler
{
// Set the prefix string based on the prefix opcode
prefixString = opcode == REP_PREFIX ? "rep " : "repne ";
// Read the next byte (the actual string instruction opcode)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
stringOpcode = Decoder.ReadByte();
if (!StringInstructions.ContainsKey(stringOpcode))
{
return false;
}
}
// Get the mnemonic and operands for the string instruction
if (StringInstructions.TryGetValue(stringOpcode, out var instructionInfo))
{
// Set the mnemonic with the prefix if present
instruction.Mnemonic = prefixString + instructionInfo.Mnemonic;
// Set the operands
instruction.Operands = instructionInfo.Operands;
return true;
}
// This shouldn't happen if CanHandle is called first
return false;
}
}
}

View File

@ -34,9 +34,7 @@ public class SubAlImm8Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -38,10 +38,7 @@ public class SubAxImm16Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sub";
int position = Decoder.GetPosition();
// Check if we have enough bytes for the immediate value
if (position + 1 >= Length)
if (!Decoder.CanReadUShort())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class SubImmFromRm32Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 5 (SUB)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 5; // 5 = SUB
@ -48,25 +47,16 @@ public class SubImmFromRm32Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sub";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
// Extract the fields from the ModR/M byte
// Let the ModRMDecoder handle the ModR/M byte and any additional bytes (SIB, displacement)
// This will update the decoder position to point after the ModR/M and any additional bytes
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class SubImmFromRm8Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 5 (SUB)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte) ((modRM & 0x38) >> 3);
return reg == 5; // 5 = SUB
@ -52,8 +51,7 @@ public class SubImmFromRm8Handler : InstructionHandler
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Read the immediate byte
var position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -38,9 +38,7 @@ public class SubR16Rm16Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sub";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -34,9 +34,7 @@ public class SubR32Rm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,7 @@ public class SubR8Rm8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sub";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -38,9 +38,7 @@ public class SubRm16R16Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sub";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -59,7 +57,6 @@ public class SubRm16R16Handler : InstructionHandler
}
else // Memory operand
{
// Replace "dword" with "word" in the memory operand
destOperand = destOperand.Replace("dword", "word");
instruction.Operands = $"{destOperand}, {regName}";

View File

@ -34,9 +34,7 @@ public class SubRm32R32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,7 @@ public class SubRm8R8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "sub";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,7 @@ public class TestAlImmHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "test";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,7 @@ public class TestEaxImmHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "test";
int position = Decoder.GetPosition();
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false;
}

View File

@ -50,8 +50,12 @@ public class TestImmWithRm32Handler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
// Set the mnemonic
instruction.Mnemonic = "test";
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();

View File

@ -23,7 +23,7 @@ public class XchgEaxRegHandler : InstructionHandler
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode >= 0x90 && opcode <= 0x97;
return opcode >= 0x91 && opcode <= 0x97;
}
/// <summary>
@ -34,14 +34,6 @@ public class XchgEaxRegHandler : InstructionHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
// Special case for NOP (XCHG EAX, EAX)
if (opcode == 0x90)
{
instruction.Mnemonic = "nop";
instruction.Operands = "";
return true;
}
// Set the mnemonic
instruction.Mnemonic = "xchg";

View File

@ -37,9 +37,7 @@ public class XorAlImmHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,10 +37,8 @@ public class XorAxImm16Handler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position + 1 >= Length)
if (!Decoder.CanReadUShort())
{
return false;
}

View File

@ -37,9 +37,7 @@ public class XorEaxImmHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position + 4 > Length)
if (!Decoder.CanReadUInt())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class XorImmWithRm16SignExtendedHandler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm16SignExtendedHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -78,16 +75,12 @@ public class XorImmWithRm16SignExtendedHandler : InstructionHandler
}
}
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value (sign-extended from 8 to 16 bits)
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the immediate value and sign-extend it to 16 bits
short imm16 = (sbyte)Decoder.ReadByte();
// Format the immediate value

View File

@ -27,11 +27,10 @@ public class XorImmWithRm32Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm32Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -58,16 +55,12 @@ public class XorImmWithRm32Handler : InstructionHandler
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value
if (position + 3 >= Length)
if (!Decoder.CanReadUInt())
{
return false;
}
// Read the immediate value using the decoder
var imm = Decoder.ReadUInt32();
// Format the immediate value

View File

@ -27,11 +27,10 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -58,11 +55,8 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value (sign-extended from 8 to 32 bits)
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -27,11 +27,10 @@ public class XorImmWithRm8Handler : InstructionHandler
return false;
// Check if the reg field of the ModR/M byte is 6 (XOR)
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
return false;
byte modRM = CodeBuffer[position];
byte modRM = CodeBuffer[Decoder.GetPosition()];
byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 6; // 6 = XOR
@ -48,9 +47,7 @@ public class XorImmWithRm8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
@ -58,9 +55,6 @@ public class XorImmWithRm8Handler : InstructionHandler
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Advance past the ModR/M byte
Decoder.SetPosition(position + 1);
// If mod == 3, then the r/m field specifies a register
if (mod == 3)
{
@ -69,17 +63,12 @@ public class XorImmWithRm8Handler : InstructionHandler
}
else
{
// For memory operands, use the ModRMDecoder to get the full operand string
// Replace "dword ptr" with "byte ptr" to indicate 8-bit operation
destOperand = destOperand.Replace("dword ptr", "byte ptr");
}
// Get the updated position after ModR/M decoding
position = Decoder.GetPosition();
// Read the immediate value
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,9 +37,7 @@ public class XorMemRegHandler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -38,9 +38,7 @@ public class XorR16Rm16Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,18 +37,13 @@ public class XorR8Rm8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Advance past the ModR/M byte
Decoder.SetPosition(position + 1);
// Get register name (8-bit)
string regName = ModRMDecoder.GetRegisterName(reg, 8);

View File

@ -36,14 +36,12 @@ public class XorRegMemHandler : InstructionHandler
{
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, srcOperand) = ModRMDecoder.ReadModRM();

View File

@ -38,9 +38,7 @@ public class XorRm16R16Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}

View File

@ -37,18 +37,13 @@ public class XorRm8R8Handler : InstructionHandler
// Set the mnemonic
instruction.Mnemonic = "xor";
int position = Decoder.GetPosition();
if (position >= Length)
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
// Advance past the ModR/M byte
Decoder.SetPosition(position + 1);
// Get register name (8-bit)
string regName = ModRMDecoder.GetRegisterName(reg, 8);

View File

@ -114,26 +114,7 @@ public class MovRm32Imm32Tests
Assert.Equal("mov", instructions[1].Mnemonic);
Assert.Equal("dword ptr [esp+0x14], 0x00000000", instructions[1].Operands);
}
/// <summary>
/// Tests the MOV m32, imm32 instruction (0xC7) with incomplete immediate value
/// </summary>
[Fact]
public void TestMovM32Imm32_IncompleteImmediate()
{
// Arrange
// MOV DWORD PTR [EAX], ?? (incomplete immediate)
byte[] code = { 0xC7, 0x00, 0x78, 0x56 }; // Missing 2 bytes of immediate
// Act
Disassembler disassembler = new Disassembler(code, 0x1000);
var instructions = disassembler.Disassemble();
// Assert
Assert.True(instructions.Count > 0, "Expected at least one instruction");
Assert.Equal("NO HANDLER: mov", instructions[0].Mnemonic);
}
/// <summary>
/// Tests the MOV m32, imm32 instruction (0xC7) with instruction boundary detection
/// </summary>