mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-05-19 20:01:17 +03:00
more refactoring
This commit is contained in:
parent
f54dc10596
commit
99b93523a4
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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}";
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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}";
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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}";
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user