From f654f64c717ad08f6bce83c720cd54153e46779f Mon Sep 17 00:00:00 2001 From: bird_egop Date: Wed, 16 Apr 2025 20:43:06 +0300 Subject: [PATCH] Created dedicated Mul namespace for MUL instruction handlers. Implemented MulRm8Handler for MUL r/m8 instruction (opcode F6 /4) and moved MulRm32Handler to the new namespace. Updated InstructionHandlerFactory to register both handlers. --- .../X86/Handlers/InstructionHandlerFactory.cs | 35 +++++++-- .../X86/Handlers/Mul/MulRm32Handler.cs | 75 +++++++++++++++++++ .../X86/Handlers/Mul/MulRm8Handler.cs | 75 +++++++++++++++++++ 3 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 X86Disassembler/X86/Handlers/Mul/MulRm32Handler.cs create mode 100644 X86Disassembler/X86/Handlers/Mul/MulRm8Handler.cs 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; + } +}