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

Updated instruction handlers to use Type and StructuredOperands instead of Mnemonic and Operands

This commit is contained in:
bird_egop
2025-04-14 22:08:50 +03:00
parent c516e063e7
commit 685eeda03d
136 changed files with 3694 additions and 2584 deletions

View File

@ -0,0 +1,34 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents a memory operand with a base register in an x86 instruction (e.g., [eax])
/// </summary>
public class BaseRegisterMemoryOperand : MemoryOperand
{
/// <summary>
/// Gets or sets the base register
/// </summary>
public RegisterIndex BaseRegister { get; set; }
/// <summary>
/// Initializes a new instance of the BaseRegisterMemoryOperand class
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
public BaseRegisterMemoryOperand(RegisterIndex baseRegister, int size = 32, string? segmentOverride = null)
: base(size, segmentOverride)
{
Type = OperandType.MemoryBaseReg;
BaseRegister = baseRegister;
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
var registerName = ModRMDecoder.GetRegisterName(BaseRegister, 32);
return $"{GetSegmentPrefix()}[{registerName}]";
}
}

View File

@ -0,0 +1,33 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents a direct memory operand in an x86 instruction (e.g., [0x12345678])
/// </summary>
public class DirectMemoryOperand : MemoryOperand
{
/// <summary>
/// Gets or sets the memory address
/// </summary>
public long Address { get; set; }
/// <summary>
/// Initializes a new instance of the DirectMemoryOperand class
/// </summary>
/// <param name="address">The memory address</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
public DirectMemoryOperand(long address, int size = 32, string? segmentOverride = null)
: base(size, segmentOverride)
{
Type = OperandType.MemoryDirect;
Address = address;
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
return $"{GetSegmentPrefix()}[0x{Address:X}]";
}
}

View File

@ -0,0 +1,42 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents a memory operand with a base register and displacement in an x86 instruction (e.g., [eax+0x4])
/// </summary>
public class DisplacementMemoryOperand : MemoryOperand
{
/// <summary>
/// Gets or sets the base register
/// </summary>
public RegisterIndex BaseRegister { get; set; }
/// <summary>
/// Gets or sets the displacement value
/// </summary>
public long Displacement { get; set; }
/// <summary>
/// Initializes a new instance of the DisplacementMemoryOperand class
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
public DisplacementMemoryOperand(RegisterIndex baseRegister, long displacement, int size = 32, string? segmentOverride = null)
: base(size, segmentOverride)
{
Type = OperandType.MemoryBaseRegPlusOffset;
BaseRegister = baseRegister;
Displacement = displacement;
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
string sign = Displacement >= 0 ? "+" : "";
var registerName = ModRMDecoder.GetRegisterName(BaseRegister, 32);
return $"{GetSegmentPrefix()}[{registerName}{sign}0x{Math.Abs(Displacement):X}]";
}
}

View File

@ -0,0 +1,32 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents an FPU register operand (ST(0) to ST(7))
/// </summary>
public class FPURegisterOperand : Operand
{
/// <summary>
/// Gets the FPU register index (0-7)
/// </summary>
public FpuRegisterIndex RegisterIndex { get; }
/// <summary>
/// Initializes a new instance of the FPURegisterOperand class
/// </summary>
/// <param name="registerIndex">The FPU register index (RegisterIndex.A to RegisterIndex.Di)</param>
public FPURegisterOperand(FpuRegisterIndex registerIndex)
{
RegisterIndex = registerIndex;
}
/// <summary>
/// Returns a string representation of the FPU register operand
/// </summary>
/// <returns>A string representation of the FPU register operand</returns>
public override string ToString()
{
// Convert RegisterIndex to a numerical index (0-7)
int index = (int)RegisterIndex;
return $"ST({index})";
}
}

View File

@ -0,0 +1,32 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents an immediate value operand in an x86 instruction
/// </summary>
public class ImmediateOperand : Operand
{
/// <summary>
/// Gets or sets the immediate value
/// </summary>
public long Value { get; set; }
/// <summary>
/// Initializes a new instance of the ImmediateOperand class
/// </summary>
/// <param name="value">The immediate value</param>
/// <param name="size">The size of the value in bits</param>
public ImmediateOperand(long value, int size = 32)
{
Type = OperandType.ImmediateValue;
Value = value;
Size = size;
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
return $"0x{Value:X}";
}
}

View File

@ -0,0 +1,32 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Base class for all memory operands in an x86 instruction
/// </summary>
public abstract class MemoryOperand : Operand
{
/// <summary>
/// Gets or sets the segment override (if any)
/// </summary>
public string? SegmentOverride { get; set; }
/// <summary>
/// Initializes a new instance of the MemoryOperand class
/// </summary>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
protected MemoryOperand(int size = 32, string? segmentOverride = null)
{
Size = size;
SegmentOverride = segmentOverride;
}
/// <summary>
/// Gets the segment prefix string for display
/// </summary>
/// <returns>The segment prefix string</returns>
protected string GetSegmentPrefix()
{
return SegmentOverride != null ? $"{SegmentOverride}:" : "";
}
}

View File

@ -0,0 +1,103 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Factory class for creating operand objects
/// </summary>
public static class OperandFactory
{
/// <summary>
/// Creates a register operand
/// </summary>
/// <param name="register">The register</param>
/// <param name="size">The size of the register in bits</param>
/// <returns>A register operand</returns>
public static RegisterOperand CreateRegisterOperand(RegisterIndex register, int size = 32)
{
return new RegisterOperand(register, size);
}
/// <summary>
/// Creates an immediate value operand
/// </summary>
/// <param name="value">The immediate value</param>
/// <param name="size">The size of the value in bits</param>
/// <returns>An immediate value operand</returns>
public static ImmediateOperand CreateImmediateOperand(long value, int size = 32)
{
return new ImmediateOperand(value, size);
}
/// <summary>
/// Creates a direct memory operand
/// </summary>
/// <param name="address">The memory address</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A direct memory operand</returns>
public static DirectMemoryOperand CreateDirectMemoryOperand(long address, int size = 32, string? segmentOverride = null)
{
return new DirectMemoryOperand(address, size, segmentOverride);
}
/// <summary>
/// Creates a base register memory operand
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A base register memory operand</returns>
public static BaseRegisterMemoryOperand CreateBaseRegisterMemoryOperand(RegisterIndex baseRegister, int size = 32, string? segmentOverride = null)
{
return new BaseRegisterMemoryOperand(baseRegister, size, segmentOverride);
}
/// <summary>
/// Creates a displacement memory operand
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A displacement memory operand</returns>
public static DisplacementMemoryOperand CreateDisplacementMemoryOperand(RegisterIndex baseRegister, long displacement, int size = 32, string? segmentOverride = null)
{
return new DisplacementMemoryOperand(baseRegister, displacement, size, segmentOverride);
}
/// <summary>
/// Creates a scaled index memory operand
/// </summary>
/// <param name="indexRegister">The index register</param>
/// <param name="scale">The scale factor (1, 2, 4, or 8)</param>
/// <param name="baseRegister">The optional base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A scaled index memory operand</returns>
public static ScaledIndexMemoryOperand CreateScaledIndexMemoryOperand(RegisterIndex indexRegister, int scale, RegisterIndex? baseRegister = null,
long displacement = 0, int size = 32, string? segmentOverride = null)
{
return new ScaledIndexMemoryOperand(indexRegister, scale, baseRegister, displacement, size, segmentOverride);
}
/// <summary>
/// Creates a relative offset operand
/// </summary>
/// <param name="targetAddress">The target address</param>
/// <param name="size">The size of the offset in bits (8 or 32)</param>
/// <returns>A relative offset operand</returns>
public static RelativeOffsetOperand CreateRelativeOffsetOperand(ulong targetAddress, int size = 32)
{
return new RelativeOffsetOperand(targetAddress, size);
}
/// <summary>
/// Creates an FPU register operand
/// </summary>
/// <param name="registerIndex">The FPU register index (RegisterIndex.A to RegisterIndex.Di)</param>
/// <returns>An FPU register operand</returns>
public static FPURegisterOperand CreateFPURegisterOperand(FpuRegisterIndex registerIndex)
{
return new FPURegisterOperand(registerIndex);
}
}

View File

@ -0,0 +1,32 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents a register operand in an x86 instruction
/// </summary>
public class RegisterOperand : Operand
{
/// <summary>
/// Gets or sets the register
/// </summary>
public RegisterIndex Register { get; set; }
/// <summary>
/// Initializes a new instance of the RegisterOperand class
/// </summary>
/// <param name="register">The register</param>
/// <param name="size">The size of the register in bits</param>
public RegisterOperand(RegisterIndex register, int size = 32)
{
Type = OperandType.Register;
Register = register;
Size = size;
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
return ModRMDecoder.GetRegisterName(Register, Size);
}
}

View File

@ -0,0 +1,32 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents a relative offset operand in an x86 instruction (used for jumps and calls)
/// </summary>
public class RelativeOffsetOperand : Operand
{
/// <summary>
/// Gets or sets the target address
/// </summary>
public ulong TargetAddress { get; set; }
/// <summary>
/// Initializes a new instance of the RelativeOffsetOperand class
/// </summary>
/// <param name="targetAddress">The target address</param>
/// <param name="size">The size of the offset in bits (8 or 32)</param>
public RelativeOffsetOperand(ulong targetAddress, int size = 32)
{
Type = OperandType.RelativeOffset;
TargetAddress = targetAddress;
Size = size;
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
return $"0x{TargetAddress:X}";
}
}

View File

@ -0,0 +1,65 @@
namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents a memory operand with scale, index, and base in an x86 instruction (e.g., [eax+ecx*4+0x8])
/// </summary>
public class ScaledIndexMemoryOperand : MemoryOperand
{
/// <summary>
/// Gets or sets the base register
/// </summary>
public RegisterIndex? BaseRegister { get; set; }
/// <summary>
/// Gets or sets the index register
/// </summary>
public RegisterIndex IndexRegister { get; set; }
/// <summary>
/// Gets or sets the scale factor (1, 2, 4, or 8)
/// </summary>
public int Scale { get; set; }
/// <summary>
/// Gets or sets the displacement value
/// </summary>
public long Displacement { get; set; }
/// <summary>
/// Initializes a new instance of the ScaledIndexMemoryOperand class
/// </summary>
/// <param name="indexRegister">The index register</param>
/// <param name="scale">The scale factor (1, 2, 4, or 8)</param>
/// <param name="baseRegister">The optional base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="size">The size of the memory access in bits</param>
/// <param name="segmentOverride">Optional segment override</param>
public ScaledIndexMemoryOperand(RegisterIndex indexRegister, int scale, RegisterIndex? baseRegister = null,
long displacement = 0, int size = 32, string? segmentOverride = null)
: base(size, segmentOverride)
{
Type = OperandType.MemoryIndexed;
IndexRegister = indexRegister;
Scale = scale;
BaseRegister = baseRegister;
Displacement = displacement;
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
string baseRegPart = BaseRegister != null ? $"{BaseRegister}+" : "";
string indexPart = $"{IndexRegister}*{Scale}";
string dispPart = "";
if (Displacement != 0)
{
string sign = Displacement > 0 ? "+" : "";
dispPart = $"{sign}0x{Math.Abs(Displacement):X}";
}
return $"{GetSegmentPrefix()}[{baseRegPart}{indexPart}{dispPart}]";
}
}