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

Implemented SBB instruction handlers for the x86 disassembler

This commit is contained in:
bird_egop 2025-04-17 21:49:44 +03:00
parent a62812f71c
commit 33dc0b0fa2
6 changed files with 406 additions and 1 deletions

View File

@ -100,9 +100,20 @@ public class InstructionHandlerFactory
/// </summary> /// </summary>
private void RegisterSbbHandlers() private void RegisterSbbHandlers()
{ {
// SBB immediate handlers // SBB immediate handlers for 8-bit operands
_handlers.Add(new SbbImmFromRm8Handler(_decoder)); // SBB r/m8, imm8 (opcode 80 /3)
_handlers.Add(new SbbAlImmHandler(_decoder)); // SBB AL, imm8 (opcode 1C)
// SBB immediate handlers for 16-bit operands (with 0x66 prefix)
_handlers.Add(new SbbImmFromRm16Handler(_decoder)); // SBB r/m16, imm16 (opcode 81 /3 with 0x66 prefix)
_handlers.Add(new SbbImmFromRm16SignExtendedHandler(_decoder)); // SBB r/m16, imm8 (opcode 83 /3 with 0x66 prefix)
// SBB immediate handlers for 32-bit operands
_handlers.Add(new SbbImmFromRm32Handler(_decoder)); // SBB r/m32, imm32 (opcode 81 /3) _handlers.Add(new SbbImmFromRm32Handler(_decoder)); // SBB r/m32, imm32 (opcode 81 /3)
_handlers.Add(new SbbImmFromRm32SignExtendedHandler(_decoder)); // SBB r/m32, imm8 (opcode 83 /3) _handlers.Add(new SbbImmFromRm32SignExtendedHandler(_decoder)); // SBB r/m32, imm8 (opcode 83 /3)
// SBB accumulator handlers
_handlers.Add(new SbbAccumulatorImmHandler(_decoder)); // SBB AX/EAX, imm16/32 (opcode 1D)
} }
/// <summary> /// <summary>
@ -140,6 +151,15 @@ public class InstructionHandlerFactory
// Add Return handlers // Add Return handlers
_handlers.Add(new RetHandler(_decoder)); _handlers.Add(new RetHandler(_decoder));
_handlers.Add(new RetImmHandler(_decoder)); _handlers.Add(new RetImmHandler(_decoder));
// Add Far Return handlers
// 16-bit handlers with operand size prefix (must come first)
_handlers.Add(new Retf16Handler(_decoder)); // RETF (16-bit) (opcode 0xCB with 0x66 prefix)
_handlers.Add(new RetfImm16Handler(_decoder)); // RETF imm16 (16-bit) (opcode 0xCA with 0x66 prefix)
// 32-bit handlers (default)
_handlers.Add(new RetfHandler(_decoder)); // RETF (32-bit) (opcode 0xCB)
_handlers.Add(new RetfImmHandler(_decoder)); // RETF imm16 (32-bit) (opcode 0xCA)
} }
/// <summary> /// <summary>

View File

@ -0,0 +1,70 @@
namespace X86Disassembler.X86.Handlers.Sbb;
using Operands;
/// <summary>
/// Handler for SBB AX/EAX, imm16/32 instruction (0x1D)
/// </summary>
public class SbbAccumulatorImmHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the SbbAccumulatorImmHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public SbbAccumulatorImmHandler(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)
{
return opcode == 0x1D;
}
/// <summary>
/// Decodes a SBB AX/EAX, imm16/32 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)
{
// Set the instruction type
instruction.Type = InstructionType.Sbb;
// Determine operand size based on prefix
int operandSize = Decoder.HasOperandSizePrefix() ? 16 : 32;
// Check if we have enough bytes for the immediate value
if (operandSize == 16 && !Decoder.CanReadUShort())
{
return false;
}
else if (operandSize == 32 && !Decoder.CanReadUInt())
{
return false;
}
// Create the accumulator register operand (AX or EAX)
var accumulatorOperand = OperandFactory.CreateRegisterOperand(RegisterIndex.A, operandSize);
// Read and create the immediate operand based on operand size
var immOperand = operandSize == 16
? OperandFactory.CreateImmediateOperand(Decoder.ReadUInt16(), operandSize)
: OperandFactory.CreateImmediateOperand(Decoder.ReadUInt32(), operandSize);
// Set the structured operands
instruction.StructuredOperands =
[
accumulatorOperand,
immOperand
];
return true;
}
}

View File

@ -0,0 +1,64 @@
namespace X86Disassembler.X86.Handlers.Sbb;
using Operands;
/// <summary>
/// Handler for SBB AL, imm8 instruction (0x1C)
/// </summary>
public class SbbAlImmHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the SbbAlImmHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public SbbAlImmHandler(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)
{
return opcode == 0x1C;
}
/// <summary>
/// Decodes a SBB AL, imm8 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)
{
// Set the instruction type
instruction.Type = InstructionType.Sbb;
// Create the AL register operand
var alOperand = OperandFactory.CreateRegisterOperand(RegisterIndex.A, 8);
// Check if we have enough bytes for the immediate value
if (!Decoder.CanReadByte())
{
return false;
}
// Read the immediate value
byte imm8 = Decoder.ReadByte();
// Create the immediate operand
var immOperand = OperandFactory.CreateImmediateOperand(imm8, 8);
// Set the structured operands
instruction.StructuredOperands =
[
alOperand,
immOperand
];
return true;
}
}

View File

@ -0,0 +1,85 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.Sbb;
/// <summary>
/// Handler for SBB r/m16, imm16 instruction (0x81 /3 with 0x66 prefix)
/// </summary>
public class SbbImmFromRm16Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the SbbImmFromRm16Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public SbbImmFromRm16Handler(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)
{
if (opcode != 0x81)
return false;
// Must have operand size prefix for 16-bit operation
if (!Decoder.HasOperandSizePrefix())
return false;
// Check if the reg field of the ModR/M byte is 3 (SBB)
if (!Decoder.CanReadByte())
return false;
var reg = ModRMDecoder.PeakModRMReg();
return reg == 3; // 3 = SBB
}
/// <summary>
/// Decodes a SBB r/m16, imm16 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)
{
// Set the instruction type
instruction.Type = InstructionType.Sbb;
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
// For SBB r/m16, imm16 (0x81 /3 with 0x66 prefix):
// - The r/m field with mod specifies the destination operand (register or memory)
// - The immediate value is the source operand
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM16();
// Check if we have enough bytes for the immediate value
if (!Decoder.CanReadUShort())
{
return false;
}
// Read the immediate value
ushort imm16 = Decoder.ReadUInt16();
// Create the immediate operand
var sourceOperand = OperandFactory.CreateImmediateOperand(imm16, 16);
// Set the structured operands
instruction.StructuredOperands =
[
destinationOperand,
sourceOperand
];
return true;
}
}

View File

@ -0,0 +1,85 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.Sbb;
/// <summary>
/// Handler for SBB r/m16, imm8 (sign-extended) instruction (0x83 /3 with 0x66 prefix)
/// </summary>
public class SbbImmFromRm16SignExtendedHandler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the SbbImmFromRm16SignExtendedHandler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public SbbImmFromRm16SignExtendedHandler(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)
{
if (opcode != 0x83)
return false;
// Must have operand size prefix for 16-bit operation
if (!Decoder.HasOperandSizePrefix())
return false;
// Check if the reg field of the ModR/M byte is 3 (SBB)
if (!Decoder.CanReadByte())
return false;
var reg = ModRMDecoder.PeakModRMReg();
return reg == 3; // 3 = SBB
}
/// <summary>
/// Decodes a SBB r/m16, imm8 (sign-extended) 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)
{
// Set the instruction type
instruction.Type = InstructionType.Sbb;
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
// For SBB r/m16, imm8 (sign-extended) (0x83 /3 with 0x66 prefix):
// - The r/m field with mod specifies the destination operand (register or memory)
// - The immediate value is the source operand
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM16();
// Check if we have enough bytes for the immediate value
if (!Decoder.CanReadByte())
{
return false;
}
// Sign-extend to 16 bits
sbyte imm8 = (sbyte)Decoder.ReadByte();
// Create the immediate operand with sign extension
var sourceOperand = OperandFactory.CreateImmediateOperand((ushort)imm8, 16);
// Set the structured operands
instruction.StructuredOperands =
[
destinationOperand,
sourceOperand
];
return true;
}
}

View File

@ -0,0 +1,81 @@
using X86Disassembler.X86.Operands;
namespace X86Disassembler.X86.Handlers.Sbb;
/// <summary>
/// Handler for SBB r/m8, imm8 instruction (0x80 /3)
/// </summary>
public class SbbImmFromRm8Handler : InstructionHandler
{
/// <summary>
/// Initializes a new instance of the SbbImmFromRm8Handler class
/// </summary>
/// <param name="decoder">The instruction decoder that owns this handler</param>
public SbbImmFromRm8Handler(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)
{
if (opcode != 0x80)
return false;
// Check if the reg field of the ModR/M byte is 3 (SBB)
if (!Decoder.CanReadByte())
return false;
var reg = ModRMDecoder.PeakModRMReg();
return reg == 3; // 3 = SBB
}
/// <summary>
/// Decodes a SBB r/m8, imm8 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)
{
// Set the instruction type
instruction.Type = InstructionType.Sbb;
if (!Decoder.CanReadByte())
{
return false;
}
// Read the ModR/M byte
// For SBB r/m8, imm8 (0x80 /3):
// - The r/m field with mod specifies the destination operand (register or memory)
// - The immediate value is the source operand
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Check if we have enough bytes for the immediate value
if (!Decoder.CanReadByte())
{
return false;
}
// Read the immediate value
byte imm8 = Decoder.ReadByte();
// Create the immediate operand
var sourceOperand = OperandFactory.CreateImmediateOperand(imm8, 8);
// Set the structured operands
instruction.StructuredOperands =
[
destinationOperand,
sourceOperand
];
return true;
}
}