diff --git a/X86Disassembler/X86/Handlers/Add/AddEaxImmHandler.cs b/X86Disassembler/X86/Handlers/Add/AddEaxImmHandler.cs new file mode 100644 index 0000000..2944c7c --- /dev/null +++ b/X86Disassembler/X86/Handlers/Add/AddEaxImmHandler.cs @@ -0,0 +1,57 @@ +namespace X86Disassembler.X86.Handlers.Add; + +/// +/// Handler for ADD EAX, imm32 instruction (0x05) +/// +public class AddEaxImmHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the AddEaxImmHandler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public AddEaxImmHandler(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) + { + return opcode == 0x05; + } + + /// + /// Decodes an ADD EAX, 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"; + + // Read the immediate value + int position = Decoder.GetPosition(); + if (position + 4 > Length) + { + // Not enough bytes for the immediate value + instruction.Operands = "eax, ??"; + return true; // Still return true as we've set a valid mnemonic and operands + } + + // Read the 32-bit immediate value + uint imm32 = Decoder.ReadUInt32(); + + // Set the operands + instruction.Operands = $"eax, 0x{imm32:X8}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs index 25ddf6e..0424ca2 100644 --- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs +++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs @@ -249,6 +249,7 @@ public class InstructionHandlerFactory // Add ADD handlers _handlers.Add(new AddR32Rm32Handler(_codeBuffer, _decoder, _length)); _handlers.Add(new AddRm32R32Handler(_codeBuffer, _decoder, _length)); + _handlers.Add(new AddEaxImmHandler(_codeBuffer, _decoder, _length)); // Add ADD immediate handlers from ArithmeticImmediate namespace _handlers.Add(new AddImmToRm8Handler(_codeBuffer, _decoder, _length)); diff --git a/X86DisassemblerTests/AddEaxImmHandlerTests.cs b/X86DisassemblerTests/AddEaxImmHandlerTests.cs new file mode 100644 index 0000000..009757b --- /dev/null +++ b/X86DisassemblerTests/AddEaxImmHandlerTests.cs @@ -0,0 +1,52 @@ +namespace X86DisassemblerTests; + +using System; +using Xunit; +using X86Disassembler.X86; +using X86Disassembler.X86.Handlers.Add; + +/// +/// Tests for ADD EAX, imm32 instruction handler +/// +public class AddEaxImmHandlerTests +{ + /// + /// Tests the AddEaxImmHandler for decoding ADD EAX, imm32 instruction + /// + [Fact] + public void AddEaxImmHandler_DecodesAddEaxImm32_Correctly() + { + // Arrange + // ADD EAX, 0x12345678 (05 78 56 34 12) + byte[] codeBuffer = new byte[] { 0x05, 0x78, 0x56, 0x34, 0x12 }; + var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length); + + // Act + var instruction = decoder.DecodeInstruction(); + + // Assert + Assert.NotNull(instruction); + Assert.Equal("add", instruction.Mnemonic); + Assert.Equal("eax, 0x12345678", instruction.Operands); + } + + /// + /// Tests the AddEaxImmHandler for handling insufficient bytes + /// + [Fact] + public void AddEaxImmHandler_HandlesInsufficientBytes_Gracefully() + { + // Arrange + // ADD EAX, ?? (05) - missing immediate value + byte[] codeBuffer = new byte[] { 0x05 }; + var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length); + + // Act + var instruction = decoder.DecodeInstruction(); + + // Assert + Assert.NotNull(instruction); + Assert.Equal("add", instruction.Mnemonic); + Assert.Equal("eax, ??", instruction.Operands); + } +}