diff --git a/X86Disassembler/X86/Handlers/Group1/AdcImmToRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/AdcImmToRm32Handler.cs
new file mode 100644
index 0000000..ce9a7f1
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/AdcImmToRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for ADC r/m32, imm32 instruction (0x81 /2)
+///
+public class AdcImmToRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the AdcImmToRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public AdcImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 2 (ADC)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 2; // 2 = ADC
+ }
+
+ ///
+ /// Decodes an ADC r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "adc";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 2 for ADC
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/AdcImmToRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/AdcImmToRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..5e4b318
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/AdcImmToRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for ADC r/m32, imm8 (sign-extended) instruction (0x83 /2)
+///
+public class AdcImmToRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the AdcImmToRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public AdcImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 2 (ADC)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 2; // 2 = ADC
+ }
+
+ ///
+ /// Decodes an ADC r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "adc";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 2 for ADC
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value (sign-extended from 8 to 32 bits)
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ sbyte imm8 = (sbyte)CodeBuffer[position];
+ int imm32 = imm8; // Sign-extend to 32 bits
+ Decoder.SetPosition(position + 1);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/AddImmToRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/AddImmToRm32Handler.cs
new file mode 100644
index 0000000..aef61de
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/AddImmToRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for ADD r/m32, imm32 instruction (0x81 /0)
+///
+public class AddImmToRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the AddImmToRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public AddImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 0 (ADD)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 0; // 0 = ADD
+ }
+
+ ///
+ /// Decodes an ADD r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "add";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for ADD
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/AddImmToRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/AddImmToRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..d546f76
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/AddImmToRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for ADD r/m32, imm8 (sign-extended) instruction (0x83 /0)
+///
+public class AddImmToRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the AddImmToRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public AddImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 0 (ADD)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 0; // 0 = ADD
+ }
+
+ ///
+ /// Decodes an ADD r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "add";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for ADD
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the immediate value as a signed byte and sign-extend it
+ sbyte imm8 = (sbyte)CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{(uint)imm8:X2}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/AddImmToRm8Handler.cs b/X86Disassembler/X86/Handlers/Group1/AddImmToRm8Handler.cs
new file mode 100644
index 0000000..be37a80
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/AddImmToRm8Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for ADD r/m8, imm8 instruction (0x80 /0)
+///
+public class AddImmToRm8Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the AddImmToRm8Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public AddImmToRm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x80)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 0 (ADD)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 0; // 0 = ADD
+ }
+
+ ///
+ /// Decodes an ADD r/m8, imm8 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "add";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for ADD
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ byte imm8 = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm8:X2}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/AndImmWithRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/AndImmWithRm32Handler.cs
new file mode 100644
index 0000000..b58ef6d
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/AndImmWithRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for AND r/m32, imm32 instruction (0x81 /4)
+///
+public class AndImmWithRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the AndImmWithRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public AndImmWithRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 4 (AND)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 4; // 4 = AND
+ }
+
+ ///
+ /// Decodes an AND r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "and";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 4 for AND
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/AndImmWithRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/AndImmWithRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..f2c7c68
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/AndImmWithRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for AND r/m32, imm8 (sign-extended) instruction (0x83 /4)
+///
+public class AndImmWithRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the AndImmWithRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public AndImmWithRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 4 (AND)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 4; // 4 = AND
+ }
+
+ ///
+ /// Decodes an AND r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "and";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 4 for AND
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value (sign-extended from 8 to 32 bits)
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ sbyte imm8 = (sbyte)CodeBuffer[position];
+ int imm32 = imm8; // Sign-extend to 32 bits
+ Decoder.SetPosition(position + 1);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/CmpImmWithRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/CmpImmWithRm32Handler.cs
new file mode 100644
index 0000000..9e688ae
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/CmpImmWithRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for CMP r/m32, imm32 instruction (0x81 /7)
+///
+public class CmpImmWithRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the CmpImmWithRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public CmpImmWithRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 7 (CMP)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 7; // 7 = CMP
+ }
+
+ ///
+ /// Decodes a CMP r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "cmp";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 7 for CMP
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/CmpImmWithRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/CmpImmWithRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..b73d511
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/CmpImmWithRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for CMP r/m32, imm8 (sign-extended) instruction (0x83 /7)
+///
+public class CmpImmWithRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the CmpImmWithRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public CmpImmWithRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 7 (CMP)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 7; // 7 = CMP
+ }
+
+ ///
+ /// Decodes a CMP r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "cmp";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 7 for CMP
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the immediate value as a signed byte and sign-extend it
+ sbyte imm8 = (sbyte)CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{(uint)imm8:X2}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/Group1BaseHandler.cs b/X86Disassembler/X86/Handlers/Group1/Group1BaseHandler.cs
new file mode 100644
index 0000000..84dda24
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/Group1BaseHandler.cs
@@ -0,0 +1,44 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Base class for Group 1 instruction handlers (ADD, OR, ADC, SBB, AND, SUB, XOR, CMP)
+///
+public abstract class Group1BaseHandler : InstructionHandler
+{
+ // ModR/M decoder
+ protected readonly ModRMDecoder _modRMDecoder;
+
+ ///
+ /// Initializes a new instance of the Group1BaseHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ protected Group1BaseHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ _modRMDecoder = new ModRMDecoder(codeBuffer, decoder, length);
+ }
+
+ ///
+ /// Gets the 32-bit register name for the given register index
+ ///
+ /// The register index
+ /// The register name
+ protected static string GetRegister32(byte reg)
+ {
+ string[] registerNames = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };
+ return registerNames[reg & 0x07];
+ }
+
+ ///
+ /// Gets the 8-bit register name for the given register index
+ ///
+ /// The register index
+ /// The register name
+ protected static string GetRegister8(byte reg)
+ {
+ string[] registerNames = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
+ return registerNames[reg & 0x07];
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/OrImmToRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/OrImmToRm32Handler.cs
new file mode 100644
index 0000000..055d548
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/OrImmToRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for OR r/m32, imm32 instruction (0x81 /1)
+///
+public class OrImmToRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the OrImmToRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public OrImmToRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 1 (OR)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 1; // 1 = OR
+ }
+
+ ///
+ /// Decodes an OR r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "or";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 1 for OR
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/OrImmToRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/OrImmToRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..7e9d204
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/OrImmToRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for OR r/m32, imm8 (sign-extended) instruction (0x83 /1)
+///
+public class OrImmToRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the OrImmToRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public OrImmToRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 1 (OR)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 1; // 1 = OR
+ }
+
+ ///
+ /// Decodes an OR r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "or";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 1 for OR
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value (sign-extended from 8 to 32 bits)
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ sbyte imm8 = (sbyte)CodeBuffer[position];
+ int imm32 = imm8; // Sign-extend to 32 bits
+ Decoder.SetPosition(position + 1);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/OrImmToRm8Handler.cs b/X86Disassembler/X86/Handlers/Group1/OrImmToRm8Handler.cs
new file mode 100644
index 0000000..56f5db4
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/OrImmToRm8Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for OR r/m8, imm8 instruction (0x80 /1)
+///
+public class OrImmToRm8Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the OrImmToRm8Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public OrImmToRm8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x80)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 1 (OR)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 1; // 1 = OR
+ }
+
+ ///
+ /// Decodes an OR r/m8, imm8 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "or";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 1 for OR
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ byte imm8 = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm8:X2}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/SbbImmFromRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/SbbImmFromRm32Handler.cs
new file mode 100644
index 0000000..c30f475
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/SbbImmFromRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for SBB r/m32, imm32 instruction (0x81 /3)
+///
+public class SbbImmFromRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the SbbImmFromRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public SbbImmFromRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 3 (SBB)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 3; // 3 = SBB
+ }
+
+ ///
+ /// Decodes a SBB r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "sbb";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 3 for SBB
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/SbbImmFromRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/SbbImmFromRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..0dce041
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/SbbImmFromRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for SBB r/m32, imm8 (sign-extended) instruction (0x83 /3)
+///
+public class SbbImmFromRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the SbbImmFromRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public SbbImmFromRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 3 (SBB)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 3; // 3 = SBB
+ }
+
+ ///
+ /// Decodes a SBB r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "sbb";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 3 for SBB
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value (sign-extended from 8 to 32 bits)
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ sbyte imm8 = (sbyte)CodeBuffer[position];
+ int imm32 = imm8; // Sign-extend to 32 bits
+ Decoder.SetPosition(position + 1);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/SubImmFromRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/SubImmFromRm32Handler.cs
new file mode 100644
index 0000000..e696c53
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/SubImmFromRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for SUB r/m32, imm32 instruction (0x81 /5)
+///
+public class SubImmFromRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the SubImmFromRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public SubImmFromRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 5 (SUB)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 5; // 5 = SUB
+ }
+
+ ///
+ /// Decodes a SUB r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "sub";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 5 for SUB
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/SubImmFromRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/SubImmFromRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..84ee45a
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/SubImmFromRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for SUB r/m32, imm8 (sign-extended) instruction (0x83 /5)
+///
+public class SubImmFromRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the SubImmFromRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public SubImmFromRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 5 (SUB)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 5; // 5 = SUB
+ }
+
+ ///
+ /// Decodes a SUB r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "sub";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 5 for SUB
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the immediate value as a signed byte and sign-extend it
+ sbyte imm8 = (sbyte)CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{(uint)imm8:X2}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/XorImmWithRm32Handler.cs b/X86Disassembler/X86/Handlers/Group1/XorImmWithRm32Handler.cs
new file mode 100644
index 0000000..7b5a8cb
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/XorImmWithRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for XOR r/m32, imm32 instruction (0x81 /6)
+///
+public class XorImmWithRm32Handler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the XorImmWithRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public XorImmWithRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x81)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 6 (XOR)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 6; // 6 = XOR
+ }
+
+ ///
+ /// Decodes a XOR r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "xor";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 6 for XOR
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group1/XorImmWithRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Group1/XorImmWithRm32SignExtendedHandler.cs
new file mode 100644
index 0000000..c446099
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group1/XorImmWithRm32SignExtendedHandler.cs
@@ -0,0 +1,85 @@
+namespace X86Disassembler.X86.Handlers.Group1;
+
+///
+/// Handler for XOR r/m32, imm8 (sign-extended) instruction (0x83 /6)
+///
+public class XorImmWithRm32SignExtendedHandler : Group1BaseHandler
+{
+ ///
+ /// Initializes a new instance of the XorImmWithRm32SignExtendedHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public XorImmWithRm32SignExtendedHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0x83)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 6 (XOR)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 6; // 6 = XOR
+ }
+
+ ///
+ /// Decodes a XOR r/m32, imm8 (sign-extended) instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "xor";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 6 for XOR
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value (sign-extended from 8 to 32 bits)
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ sbyte imm8 = (sbyte)CodeBuffer[position];
+ int imm32 = imm8; // Sign-extend to 32 bits
+ Decoder.SetPosition(position + 1);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/DivRm32Handler.cs b/X86Disassembler/X86/Handlers/Group3/DivRm32Handler.cs
new file mode 100644
index 0000000..f3a340f
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/DivRm32Handler.cs
@@ -0,0 +1,75 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Handler for DIV r/m32 instruction (0xF7 /6)
+///
+public class DivRm32Handler : Group3BaseHandler
+{
+ ///
+ /// Initializes a new instance of the DivRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public DivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0xF7)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 6 (DIV)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 6; // 6 = DIV
+ }
+
+ ///
+ /// Decodes a DIV r/m32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "div";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 6 for DIV
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the operand
+ string operand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Set the operands
+ instruction.Operands = operand;
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/Group3BaseHandler.cs b/X86Disassembler/X86/Handlers/Group3/Group3BaseHandler.cs
new file mode 100644
index 0000000..bb80d72
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/Group3BaseHandler.cs
@@ -0,0 +1,44 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Base class for Group 3 instruction handlers (TEST, NOT, NEG, MUL, IMUL, DIV, IDIV)
+///
+public abstract class Group3BaseHandler : InstructionHandler
+{
+ // ModR/M decoder
+ protected readonly ModRMDecoder _modRMDecoder;
+
+ ///
+ /// Initializes a new instance of the Group3BaseHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ protected Group3BaseHandler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ _modRMDecoder = new ModRMDecoder(codeBuffer, decoder, length);
+ }
+
+ ///
+ /// Gets the 32-bit register name for the given register index
+ ///
+ /// The register index
+ /// The register name
+ protected static string GetRegister32(byte reg)
+ {
+ string[] registerNames = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };
+ return registerNames[reg & 0x07];
+ }
+
+ ///
+ /// Gets the 8-bit register name for the given register index
+ ///
+ /// The register index
+ /// The register name
+ protected static string GetRegister8(byte reg)
+ {
+ string[] registerNames = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
+ return registerNames[reg & 0x07];
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/IdivRm32Handler.cs b/X86Disassembler/X86/Handlers/Group3/IdivRm32Handler.cs
new file mode 100644
index 0000000..b28a3ae
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/IdivRm32Handler.cs
@@ -0,0 +1,75 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Handler for IDIV r/m32 instruction (0xF7 /7)
+///
+public class IdivRm32Handler : Group3BaseHandler
+{
+ ///
+ /// Initializes a new instance of the IdivRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public IdivRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0xF7)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 7 (IDIV)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 7; // 7 = IDIV
+ }
+
+ ///
+ /// Decodes an IDIV r/m32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "idiv";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 7 for IDIV
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the operand
+ string operand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Set the operands
+ instruction.Operands = operand;
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/ImulRm32Handler.cs b/X86Disassembler/X86/Handlers/Group3/ImulRm32Handler.cs
new file mode 100644
index 0000000..5eb508c
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/ImulRm32Handler.cs
@@ -0,0 +1,75 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Handler for IMUL r/m32 instruction (0xF7 /5)
+///
+public class ImulRm32Handler : Group3BaseHandler
+{
+ ///
+ /// Initializes a new instance of the ImulRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public ImulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0xF7)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 5 (IMUL)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 5; // 5 = IMUL
+ }
+
+ ///
+ /// Decodes an IMUL r/m32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "imul";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 5 for IMUL
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the operand
+ string operand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Set the operands
+ instruction.Operands = operand;
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/MulRm32Handler.cs b/X86Disassembler/X86/Handlers/Group3/MulRm32Handler.cs
new file mode 100644
index 0000000..a4cf90c
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/MulRm32Handler.cs
@@ -0,0 +1,75 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Handler for MUL r/m32 instruction (0xF7 /4)
+///
+public class MulRm32Handler : Group3BaseHandler
+{
+ ///
+ /// Initializes a new instance of the MulRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public MulRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0xF7)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 4 (MUL)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 4; // 4 = MUL
+ }
+
+ ///
+ /// Decodes a MUL r/m32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "mul";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 4 for MUL
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the operand
+ string operand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Set the operands
+ instruction.Operands = operand;
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/NegRm32Handler.cs b/X86Disassembler/X86/Handlers/Group3/NegRm32Handler.cs
new file mode 100644
index 0000000..caefa3c
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/NegRm32Handler.cs
@@ -0,0 +1,75 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Handler for NEG r/m32 instruction (0xF7 /3)
+///
+public class NegRm32Handler : Group3BaseHandler
+{
+ ///
+ /// Initializes a new instance of the NegRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public NegRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0xF7)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 3 (NEG)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 3; // 3 = NEG
+ }
+
+ ///
+ /// Decodes a NEG r/m32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "neg";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 3 for NEG
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the operand
+ string operand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Set the operands
+ instruction.Operands = operand;
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/NotRm32Handler.cs b/X86Disassembler/X86/Handlers/Group3/NotRm32Handler.cs
new file mode 100644
index 0000000..bb1a6ff
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/NotRm32Handler.cs
@@ -0,0 +1,75 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Handler for NOT r/m32 instruction (0xF7 /2)
+///
+public class NotRm32Handler : Group3BaseHandler
+{
+ ///
+ /// Initializes a new instance of the NotRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public NotRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0xF7)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 2 (NOT)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 2; // 2 = NOT
+ }
+
+ ///
+ /// Decodes a NOT r/m32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "not";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 2 for NOT
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the operand
+ string operand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Set the operands
+ instruction.Operands = operand;
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Group3/TestImmWithRm32Handler.cs b/X86Disassembler/X86/Handlers/Group3/TestImmWithRm32Handler.cs
new file mode 100644
index 0000000..2c9832e
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Group3/TestImmWithRm32Handler.cs
@@ -0,0 +1,84 @@
+namespace X86Disassembler.X86.Handlers.Group3;
+
+///
+/// Handler for TEST r/m32, imm32 instruction (0xF7 /0)
+///
+public class TestImmWithRm32Handler : Group3BaseHandler
+{
+ ///
+ /// Initializes a new instance of the TestImmWithRm32Handler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public TestImmWithRm32Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
+ : base(codeBuffer, decoder, length)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ if (opcode != 0xF7)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 0 (TEST)
+ int position = Decoder.GetPosition();
+ if (position >= Length)
+ return false;
+
+ byte modRM = CodeBuffer[position];
+ byte reg = (byte)((modRM & 0x38) >> 3);
+
+ return reg == 0; // 0 = TEST
+ }
+
+ ///
+ /// Decodes a TEST r/m32, imm32 instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ // Set the mnemonic
+ instruction.Mnemonic = "test";
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ byte modRM = CodeBuffer[position++];
+ Decoder.SetPosition(position);
+
+ // Extract the fields from the ModR/M byte
+ byte mod = (byte)((modRM & 0xC0) >> 6);
+ byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for TEST
+ byte rm = (byte)(modRM & 0x07);
+
+ // Decode the destination operand
+ string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
+
+ // Read the immediate value
+ if (position + 3 >= Length)
+ {
+ return false;
+ }
+
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, 0x{imm32:X8}";
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
index 7608a84..3a22e8c 100644
--- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
+++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
@@ -1,5 +1,8 @@
namespace X86Disassembler.X86.Handlers;
+using X86Disassembler.X86.Handlers.Group1;
+using X86Disassembler.X86.Handlers.Group3;
+
///
/// Factory for creating instruction handlers
///
@@ -45,13 +48,84 @@ public class InstructionHandlerFactory
_handlers.Add(new ConditionalJumpHandler(_codeBuffer, _decoder, _length));
_handlers.Add(new TwoByteConditionalJumpHandler(_codeBuffer, _decoder, _length));
+ // Register Group1 handlers
+ RegisterGroup1Handlers();
+
+ // Register Group3 handlers
+ RegisterGroup3Handlers();
+
// Register group handlers for instructions that share similar decoding logic
- _handlers.Add(new Group1Handler(_codeBuffer, _decoder, _length));
- _handlers.Add(new Group3Handler(_codeBuffer, _decoder, _length));
_handlers.Add(new FloatingPointHandler(_codeBuffer, _decoder, _length));
_handlers.Add(new DataTransferHandler(_codeBuffer, _decoder, _length));
}
+ ///
+ /// Registers the Group1 handlers
+ ///
+ private void RegisterGroup1Handlers()
+ {
+ // ADD handlers
+ _handlers.Add(new AddImmToRm8Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new AddImmToRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new AddImmToRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+
+ // OR handlers
+ _handlers.Add(new OrImmToRm8Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new OrImmToRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new OrImmToRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+
+ // ADC handlers
+ _handlers.Add(new AdcImmToRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new AdcImmToRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+
+ // SBB handlers
+ _handlers.Add(new SbbImmFromRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new SbbImmFromRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+
+ // AND handlers
+ _handlers.Add(new AndImmWithRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new AndImmWithRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+
+ // SUB handlers
+ _handlers.Add(new SubImmFromRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new SubImmFromRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+
+ // XOR handlers
+ _handlers.Add(new XorImmWithRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new XorImmWithRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+
+ // CMP handlers
+ _handlers.Add(new CmpImmWithRm32Handler(_codeBuffer, _decoder, _length));
+ _handlers.Add(new CmpImmWithRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
+ }
+
+ ///
+ /// Registers the Group3 handlers
+ ///
+ private void RegisterGroup3Handlers()
+ {
+ // TEST handler
+ _handlers.Add(new TestImmWithRm32Handler(_codeBuffer, _decoder, _length));
+
+ // NOT handler
+ _handlers.Add(new NotRm32Handler(_codeBuffer, _decoder, _length));
+
+ // NEG handler
+ _handlers.Add(new NegRm32Handler(_codeBuffer, _decoder, _length));
+
+ // MUL handler
+ _handlers.Add(new MulRm32Handler(_codeBuffer, _decoder, _length));
+
+ // IMUL handler
+ _handlers.Add(new ImulRm32Handler(_codeBuffer, _decoder, _length));
+
+ // DIV handler
+ _handlers.Add(new DivRm32Handler(_codeBuffer, _decoder, _length));
+
+ // IDIV handler
+ _handlers.Add(new IdivRm32Handler(_codeBuffer, _decoder, _length));
+ }
+
///
/// Gets a handler that can decode the given opcode
///