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

207 lines
7.1 KiB
C#

namespace X86Disassembler.X86.Operands;
/// <summary>
/// Represents a far pointer memory operand (m16:32) in an x86 instruction
/// </summary>
public class FarPointerOperand : MemoryOperand
{
/// <summary>
/// Gets the base register (if any)
/// </summary>
public RegisterIndex? BaseRegister { get; }
/// <summary>
/// Gets the index register (if any)
/// </summary>
public RegisterIndex? IndexRegister { get; }
/// <summary>
/// Gets the scale factor (if using an index register)
/// </summary>
public int Scale { get; }
/// <summary>
/// Gets the displacement value (if any)
/// </summary>
public long Displacement { get; }
/// <summary>
/// Gets the direct memory address (if any)
/// </summary>
public long? Address { get; }
/// <summary>
/// Initializes a new instance of the FarPointerOperand class for base register memory operands
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="segmentOverride">Optional segment override</param>
public FarPointerOperand(RegisterIndex baseRegister, string? segmentOverride = null)
: base(48, segmentOverride)
{
Type = OperandType.MemoryBaseReg;
BaseRegister = baseRegister;
IndexRegister = null;
Scale = 1;
Displacement = 0;
Address = null;
}
/// <summary>
/// Initializes a new instance of the FarPointerOperand class for displacement memory operands
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="segmentOverride">Optional segment override</param>
public FarPointerOperand(RegisterIndex baseRegister, long displacement, string? segmentOverride = null)
: base(48, segmentOverride)
{
Type = OperandType.MemoryBaseRegPlusOffset;
BaseRegister = baseRegister;
IndexRegister = null;
Scale = 1;
Displacement = displacement;
Address = null;
}
/// <summary>
/// Initializes a new instance of the FarPointerOperand class for scaled index memory operands
/// </summary>
/// <param name="indexRegister">The index register</param>
/// <param name="scale">The scale factor</param>
/// <param name="baseRegister">The optional base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="segmentOverride">Optional segment override</param>
public FarPointerOperand(RegisterIndex indexRegister, int scale, RegisterIndex? baseRegister = null, long displacement = 0, string? segmentOverride = null)
: base(48, segmentOverride)
{
Type = OperandType.MemoryIndexed;
BaseRegister = baseRegister;
IndexRegister = indexRegister;
Scale = scale;
Displacement = displacement;
Address = null;
}
/// <summary>
/// Initializes a new instance of the FarPointerOperand class for direct memory operands
/// </summary>
/// <param name="address">The memory address</param>
/// <param name="segmentOverride">Optional segment override</param>
public FarPointerOperand(long address, string? segmentOverride = null)
: base(48, segmentOverride)
{
Type = OperandType.MemoryDirect;
BaseRegister = null;
IndexRegister = null;
Scale = 1;
Displacement = 0;
Address = address;
}
/// <summary>
/// Creates a FarPointerOperand from an existing memory operand
/// </summary>
/// <param name="memoryOperand">The memory operand to convert</param>
/// <returns>A new FarPointerOperand with the same properties</returns>
public static FarPointerOperand FromMemoryOperand(MemoryOperand memoryOperand)
{
// Create the appropriate type of FarPointerOperand based on the source operand type
if (memoryOperand is BaseRegisterMemoryOperand baseRegMemOperand)
{
return new FarPointerOperand(baseRegMemOperand.BaseRegister, memoryOperand.SegmentOverride);
}
else if (memoryOperand is DisplacementMemoryOperand dispMemOperand)
{
return new FarPointerOperand(dispMemOperand.BaseRegister, dispMemOperand.Displacement, memoryOperand.SegmentOverride);
}
else if (memoryOperand is DirectMemoryOperand directMemOperand)
{
return new FarPointerOperand(directMemOperand.Address, memoryOperand.SegmentOverride);
}
else if (memoryOperand is ScaledIndexMemoryOperand sibMemOperand)
{
return new FarPointerOperand(sibMemOperand.IndexRegister, sibMemOperand.Scale, sibMemOperand.BaseRegister, sibMemOperand.Displacement, memoryOperand.SegmentOverride);
}
// Default case - shouldn't happen if all memory operand types are handled above
throw new System.ArgumentException("Unsupported memory operand type", nameof(memoryOperand));
}
/// <summary>
/// Returns a string representation of this operand
/// </summary>
public override string ToString()
{
string prefix = "fword ptr ";
// Add segment override if present
if (SegmentOverride != null)
{
prefix = $"{prefix}{SegmentOverride}:";
}
// Format based on operand type
return Type switch
{
OperandType.MemoryBaseReg => $"{prefix}[{RegisterMapper.GetRegisterName(BaseRegister!.Value, 32)}]",
OperandType.MemoryBaseRegPlusOffset => $"{prefix}[{RegisterMapper.GetRegisterName(BaseRegister!.Value, 32)}+0x{Displacement:X}]",
OperandType.MemoryDirect => $"{prefix}[0x{Address!.Value:X}]",
OperandType.MemoryIndexed => FormatSIBString(prefix),
_ => $"{prefix}[unknown]"
};
}
/// <summary>
/// Formats the string representation for SIB addressing mode
/// </summary>
private string FormatSIBString(string prefix)
{
string result = prefix + "[";
// Add base register if present
if (BaseRegister.HasValue)
{
result += RegisterMapper.GetRegisterName(BaseRegister.Value, 32);
}
// Add index register with scale if present
if (IndexRegister.HasValue)
{
// Add + if we already have a base register
if (BaseRegister.HasValue)
{
result += "+";
}
result += RegisterMapper.GetRegisterName(IndexRegister.Value, 32);
// Add scale if not 1
if (Scale > 1)
{
result += $"*{Scale}";
}
}
// Add displacement if non-zero
if (Displacement != 0)
{
// Format as signed value
if (Displacement > 0)
{
result += $"+0x{Displacement:X}";
}
else
{
result += $"-0x{-Displacement:X}";
}
}
result += "]";
return result;
}
}