diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
index a2c0378..e24a74c 100644
--- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
+++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
@@ -10,6 +10,8 @@ using X86Disassembler.X86.Handlers.Inc;
using X86Disassembler.X86.Handlers.Jump;
using X86Disassembler.X86.Handlers.Lea;
using X86Disassembler.X86.Handlers.Mov;
+using X86Disassembler.X86.Handlers.Mul;
+using X86Disassembler.X86.Handlers.Neg;
using X86Disassembler.X86.Handlers.Nop;
using X86Disassembler.X86.Handlers.Or;
using X86Disassembler.X86.Handlers.Pop;
@@ -62,6 +64,8 @@ public class InstructionHandlerFactory
RegisterAddHandlers();
RegisterAndHandlers();
RegisterArithmeticUnaryHandlers();
+ RegisterNegHandlers(); // Register NEG handlers
+ RegisterMulHandlers(); // Register MUL handlers
RegisterCmpHandlers();
RegisterXorHandlers();
RegisterOrHandlers();
@@ -90,13 +94,6 @@ public class InstructionHandlerFactory
// NOT handler
_handlers.Add(new NotRm32Handler(_decoder));
- // NEG handlers
- _handlers.Add(new NegRm8Handler(_decoder)); // F6 /3 - NEG r/m8
- _handlers.Add(new NegRm32Handler(_decoder)); // F7 /3 - NEG r/m32
-
- // MUL handler
- _handlers.Add(new MulRm32Handler(_decoder));
-
// IMUL handler
_handlers.Add(new ImulRm32Handler(_decoder));
@@ -441,6 +438,30 @@ public class InstructionHandlerFactory
_handlers.Add(new MultiByteNopHandler(_decoder));
}
+ ///
+ /// Registers all NEG instruction handlers
+ ///
+ private void RegisterNegHandlers()
+ {
+ // NEG r/m8 handler (F6 /3)
+ _handlers.Add(new NegRm8Handler(_decoder));
+
+ // NEG r/m32 handler (F7 /3)
+ _handlers.Add(new NegRm32Handler(_decoder));
+ }
+
+ ///
+ /// Registers all MUL instruction handlers
+ ///
+ private void RegisterMulHandlers()
+ {
+ // MUL r/m8 handler (F6 /4)
+ _handlers.Add(new MulRm8Handler(_decoder));
+
+ // MUL r/m32 handler (F7 /4)
+ _handlers.Add(new MulRm32Handler(_decoder));
+ }
+
///
/// Gets the handler that can decode the given opcode
///
diff --git a/X86Disassembler/X86/Handlers/Mul/MulRm32Handler.cs b/X86Disassembler/X86/Handlers/Mul/MulRm32Handler.cs
new file mode 100644
index 0000000..331f222
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Mul/MulRm32Handler.cs
@@ -0,0 +1,75 @@
+using X86Disassembler.X86.Operands;
+
+namespace X86Disassembler.X86.Handlers.Mul;
+
+///
+/// Handler for MUL r/m32 instruction (0xF7 /4)
+///
+public class MulRm32Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the MulRm32Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public MulRm32Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// 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)
+ if (!Decoder.CanReadByte())
+ return false;
+
+ var reg = ModRMDecoder.PeakModRMReg();
+
+ 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 instruction type
+ instruction.Type = InstructionType.Mul;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ // For MUL r/m32 (0xF7 /4):
+ // - The r/m field with mod specifies the operand (register or memory)
+ var (_, reg, _, operand) = ModRMDecoder.ReadModRM();
+
+ // Verify this is a MUL instruction
+ // The reg field should be 4 (MUL), which maps to RegisterIndex.Sp in our enum
+ if (reg != RegisterIndex.Sp)
+ {
+ return false;
+ }
+
+ // Set the structured operands
+ // MUL has only one operand
+ instruction.StructuredOperands =
+ [
+ operand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Mul/MulRm8Handler.cs b/X86Disassembler/X86/Handlers/Mul/MulRm8Handler.cs
new file mode 100644
index 0000000..0847b80
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Mul/MulRm8Handler.cs
@@ -0,0 +1,75 @@
+using X86Disassembler.X86.Operands;
+
+namespace X86Disassembler.X86.Handlers.Mul;
+
+///
+/// Handler for MUL r/m8 instruction (0xF6 /4)
+///
+public class MulRm8Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the MulRm8Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public MulRm8Handler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// 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 != 0xF6)
+ return false;
+
+ // Check if the reg field of the ModR/M byte is 4 (MUL)
+ if (!Decoder.CanReadByte())
+ return false;
+
+ var reg = ModRMDecoder.PeakModRMReg();
+
+ return reg == 4; // 4 = MUL
+ }
+
+ ///
+ /// Decodes a MUL r/m8 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 instruction type
+ instruction.Type = InstructionType.Mul;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the ModR/M byte
+ // For MUL r/m8 (0xF6 /4):
+ // - The r/m field with mod specifies the operand (register or memory)
+ var (_, reg, _, operand) = ModRMDecoder.ReadModRM8();
+
+ // Verify this is a MUL instruction
+ // The reg field should be 4 (MUL), which maps to RegisterIndex8.AH in our enum
+ if (reg != RegisterIndex8.AH)
+ {
+ return false;
+ }
+
+ // Set the structured operands
+ // MUL has only one operand
+ instruction.StructuredOperands =
+ [
+ operand
+ ];
+
+ return true;
+ }
+}