0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-06-20 08:18:36 +03:00

Refactored floating point instruction handlers for better organization and maintainability. Split generic handlers into specialized classes for DD and DF opcodes.

This commit is contained in:
bird_egop
2025-04-18 00:22:02 +03:00
parent ec56576116
commit d216c29315
62 changed files with 4985 additions and 376 deletions

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FBLD packed BCD instruction (DF /4)
/// </summary>
public class FbldHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FbldHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FbldHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FBLD is DF /4
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 4
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 4
return reg == 4 && mod != 3;
}
/// <summary>
/// Decodes a FBLD packed BCD instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fbld;
// Create an 80-bit memory operand for packed BCD
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 80);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FBSTP packed BCD instruction (DF /6)
/// </summary>
public class FbstpHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FbstpHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FbstpHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FBSTP is DF /6
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 6
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 6
return reg == 6 && mod != 3;
}
/// <summary>
/// Decodes a FBSTP packed BCD instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fbstp;
// Create an 80-bit memory operand for packed BCD
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 80);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FILD int16 instruction (DF /0)
/// </summary>
public class FildInt16Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FildInt16Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FildInt16Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FILD int16 is DF /0
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 0
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 0
return reg == 0 && mod != 3;
}
/// <summary>
/// Decodes a FILD int16 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fild;
// Create a 16-bit memory operand
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FILD int32 instruction (DB /0)
/// </summary>
public class FildInt32Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FildInt32Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FildInt32Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FILD is DB /0
if (opcode != 0xDB) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 0
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3)
return reg == 0 && mod != 3;
}
/// <summary>
/// Decodes a FILD int32 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fild;
// Create a 32-bit memory operand for integer operations
Operand memoryOperand;
if (rawOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
}
else
{
memoryOperand = rawOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FILD int64 instruction (DF /5)
/// </summary>
public class FildInt64Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FildInt64Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FildInt64Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FILD int64 is DF /5
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 5
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 5
return reg == 5 && mod != 3;
}
/// <summary>
/// Decodes a FILD int64 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fild;
// Create a 64-bit memory operand
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 64);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 64);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 64);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FIST int16 instruction (DF /2)
/// </summary>
public class FistInt16Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FistInt16Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FistInt16Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FIST int16 is DF /2
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 2
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 2
return reg == 2 && mod != 3;
}
/// <summary>
/// Decodes a FIST int16 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fist;
// Create a 16-bit memory operand
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FIST int32 instruction (DB /2)
/// </summary>
public class FistInt32Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FistInt32Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FistInt32Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FIST is DB /2
if (opcode != 0xDB) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 2
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3)
return reg == 2 && mod != 3;
}
/// <summary>
/// Decodes a FIST int32 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fist;
// Create a 32-bit memory operand for integer operations
Operand memoryOperand;
if (rawOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
}
else
{
memoryOperand = rawOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FISTP int16 instruction (DF /3)
/// </summary>
public class FistpInt16Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FistpInt16Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FistpInt16Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FISTP int16 is DF /3
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 3
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 3
return reg == 3 && mod != 3;
}
/// <summary>
/// Decodes a FISTP int16 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fistp;
// Create a 16-bit memory operand
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FISTP int32 instruction (DB /3)
/// </summary>
public class FistpInt32Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FistpInt32Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FistpInt32Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FISTP is DB /3
if (opcode != 0xDB) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 3
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3)
return reg == 3 && mod != 3;
}
/// <summary>
/// Decodes a FISTP int32 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fistp;
// Create a 32-bit memory operand for integer operations
Operand memoryOperand;
if (rawOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
}
else
{
memoryOperand = rawOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FISTP int64 instruction (DF /7)
/// </summary>
public class FistpInt64Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FistpInt64Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FistpInt64Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FISTP int64 is DF /7
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 7
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 7
return reg == 7 && mod != 3;
}
/// <summary>
/// Decodes a FISTP int64 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fistp;
// Create a 64-bit memory operand
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 64);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 64);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 64);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FISTTP int16 instruction (DF /1)
/// </summary>
public class FisttpInt16Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FisttpInt16Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FisttpInt16Handler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FISTTP int16 is DF /1
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 1
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3) with reg = 1
return reg == 1 && mod != 3;
}
/// <summary>
/// Decodes a FISTTP int16 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fisttp;
// Create a 16-bit memory operand
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 16);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseMemory.BaseRegister, 16);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 16);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 16);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FLD extended-precision instruction (DB /5)
/// </summary>
public class FldExtendedHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FldExtendedHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FldExtendedHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FLD extended-precision is DB /5
if (opcode != 0xDB) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 5
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3)
return reg == 5 && mod != 3;
}
/// <summary>
/// Decodes a FLD extended-precision instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fld;
// Create an 80-bit memory operand for extended precision operations
Operand memoryOperand;
if (rawOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 80);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
}
else
{
memoryOperand = rawOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,87 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FST ST(i) instruction (DD D0-D7)
/// </summary>
public class FstRegisterHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FstRegisterHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FstRegisterHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FST ST(i) is DD D0-D7
if (opcode != 0xDD) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 2 and mod = 3
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle register operands (mod = 3) with reg = 2
return reg == 2 && mod == 3;
}
/// <summary>
/// Decodes a FST ST(i) instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fst;
// Map rm field to FPU register index
FpuRegisterIndex stIndex = rm switch
{
RegisterIndex.A => FpuRegisterIndex.ST0,
RegisterIndex.C => FpuRegisterIndex.ST1,
RegisterIndex.D => FpuRegisterIndex.ST2,
RegisterIndex.B => FpuRegisterIndex.ST3,
RegisterIndex.Sp => FpuRegisterIndex.ST4,
RegisterIndex.Bp => FpuRegisterIndex.ST5,
RegisterIndex.Si => FpuRegisterIndex.ST6,
RegisterIndex.Di => FpuRegisterIndex.ST7,
_ => FpuRegisterIndex.ST0 // Default case, should not happen
};
// Create the FPU register operand
var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
// Set the structured operands
instruction.StructuredOperands =
[
fpuRegisterOperand
];
return true;
}
}

View File

@ -0,0 +1,70 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FSTP instruction with DF opcode (DF D0-D8)
/// </summary>
public class FstpDfHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FstpDfHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FstpDfHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FSTP with DF opcode is DF D0 or DF D8
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte is D0 (reg = 2, rm = 0, mod = 3) or D8 (reg = 3, rm = 0, mod = 3)
byte modRm = Decoder.PeakByte();
return modRm == 0xD0 || modRm == 0xD8;
}
/// <summary>
/// Decodes a FSTP instruction with DF opcode
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fstp;
// Create the FPU register operand
// For both D0 and D8, the operand is ST1
var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST1);
// Set the structured operands
instruction.StructuredOperands =
[
fpuRegisterOperand
];
return true;
}
}

View File

@ -0,0 +1,94 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FSTP extended-precision instruction (DB /7)
/// </summary>
public class FstpExtendedHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FstpExtendedHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FstpExtendedHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FSTP extended-precision is DB /7
if (opcode != 0xDB) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 7
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle memory operands (mod != 3)
return reg == 7 && mod != 3;
}
/// <summary>
/// Decodes a FSTP extended-precision instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fstp;
// Create an 80-bit memory operand for extended precision operations
Operand memoryOperand;
if (rawOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 80);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 80);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 80);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 80);
}
else
{
memoryOperand = rawOperand;
}
// Set the structured operands
instruction.StructuredOperands =
[
memoryOperand
];
return true;
}
}

View File

@ -0,0 +1,87 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FSTP ST(i) instruction (DD D8-DF)
/// </summary>
public class FstpRegisterHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FstpRegisterHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FstpRegisterHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FSTP ST(i) is DD D8-DF
if (opcode != 0xDD) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte has reg field = 3 and mod = 3
byte modRm = Decoder.PeakByte();
byte reg = (byte)((modRm >> 3) & 0x7);
byte mod = (byte)((modRm >> 6) & 0x3);
// Only handle register operands (mod = 3) with reg = 3
return reg == 3 && mod == 3;
}
/// <summary>
/// Decodes a FSTP ST(i) instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fstp;
// Map rm field to FPU register index
FpuRegisterIndex stIndex = rm switch
{
RegisterIndex.A => FpuRegisterIndex.ST0,
RegisterIndex.C => FpuRegisterIndex.ST1,
RegisterIndex.D => FpuRegisterIndex.ST2,
RegisterIndex.B => FpuRegisterIndex.ST3,
RegisterIndex.Sp => FpuRegisterIndex.ST4,
RegisterIndex.Bp => FpuRegisterIndex.ST5,
RegisterIndex.Si => FpuRegisterIndex.ST6,
RegisterIndex.Di => FpuRegisterIndex.ST7,
_ => FpuRegisterIndex.ST0 // Default case, should not happen
};
// Create the FPU register operand
var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(stIndex);
// Set the structured operands
instruction.StructuredOperands =
[
fpuRegisterOperand
];
return true;
}
}

View File

@ -0,0 +1,69 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.LoadStore;
using X86Disassembler.X86.Operands;
/// <summary>
/// Handler for FXCH instruction with DF opcode (DF C8)
/// </summary>
public class FxchDfHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the FxchDfHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public FxchDfHandler(InstructionDecoder decoder)
: base(decoder)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
// FXCH with DF opcode is DF C8
if (opcode != 0xDF) return false;
if (!Decoder.CanReadByte())
{
return false;
}
// Check if the ModR/M byte is exactly C8 (reg = 1, rm = 0, mod = 3)
byte modRm = Decoder.PeakByte();
return modRm == 0xC8;
}
/// <summary>
/// Decodes a FXCH instruction with DF opcode
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
var (mod, reg, rm, _) = ModRMDecoder.ReadModRM();
// Set the instruction type
instruction.Type = InstructionType.Fxch;
// Create the FPU register operand
var fpuRegisterOperand = OperandFactory.CreateFPURegisterOperand(FpuRegisterIndex.ST0);
// Set the structured operands
instruction.StructuredOperands =
[
fpuRegisterOperand
];
return true;
}
}