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:
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user