diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs index c9d7e3e..fca6e3f 100644 --- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs +++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs @@ -4,6 +4,7 @@ using X86Disassembler.X86.Handlers.Call; using X86Disassembler.X86.Handlers.FloatingPoint; using X86Disassembler.X86.Handlers.Jump; using X86Disassembler.X86.Handlers.Mov; +using X86Disassembler.X86.Handlers.Or; using X86Disassembler.X86.Handlers.Pop; using X86Disassembler.X86.Handlers.Push; using X86Disassembler.X86.Handlers.Ret; @@ -65,6 +66,9 @@ public class InstructionHandlerFactory // Register Xor handlers RegisterXorHandlers(); + // Register Or handlers + RegisterOrHandlers(); + // Register Data Transfer handlers RegisterDataTransferHandlers(); @@ -195,6 +199,15 @@ public class InstructionHandlerFactory _handlers.Add(new XorImmWithRm32SignExtendedHandler(_codeBuffer, _decoder, _length)); } + /// + /// Registers all Or instruction handlers + /// + private void RegisterOrHandlers() + { + // Add Or handlers + _handlers.Add(new OrR8Rm8Handler(_codeBuffer, _decoder, _length)); + } + /// /// Registers all Data Transfer instruction handlers /// diff --git a/X86Disassembler/X86/Handlers/Or/OrR8Rm8Handler.cs b/X86Disassembler/X86/Handlers/Or/OrR8Rm8Handler.cs new file mode 100644 index 0000000..97fad85 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Or/OrR8Rm8Handler.cs @@ -0,0 +1,75 @@ +namespace X86Disassembler.X86.Handlers.Or; + +/// +/// Handler for OR r8, r/m8 instruction (0x0A) +/// +public class OrR8Rm8Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the OrR8Rm8Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public OrR8Rm8Handler(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 == 0x0A; + } + + /// + /// Decodes an OR r8, 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) + { + 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); + byte rm = (byte)(modRM & 0x07); + + // Set the mnemonic + instruction.Mnemonic = "or"; + + // Get the register name + string regName = GetRegister8(reg); + + // For memory operands, set the operand + if (mod != 3) // Memory operand + { + string operand = ModRMDecoder.DecodeModRM(mod, rm, false); + // Replace dword ptr with byte ptr for 8-bit operations + operand = operand.Replace("dword ptr", "byte ptr"); + instruction.Operands = $"{regName}, {operand}"; + } + else // Register operand + { + string rmName = GetRegister8(rm); + instruction.Operands = $"{regName}, {rmName}"; + } + + return true; + } +} diff --git a/X86Disassembler/X86/OpcodeMap.cs b/X86Disassembler/X86/OpcodeMap.cs index f86457e..5cd9736 100644 --- a/X86Disassembler/X86/OpcodeMap.cs +++ b/X86Disassembler/X86/OpcodeMap.cs @@ -41,6 +41,12 @@ public static class OpcodeMap OneByteOpcodes[0xDE] = "fiadd"; OneByteOpcodes[0xDF] = "fistp"; + // OR instructions + OneByteOpcodes[0x0A] = "or"; // OR r8, r/m8 + OneByteOpcodes[0x0B] = "or"; // OR r32, r/m32 + OneByteOpcodes[0x0C] = "or"; // OR AL, imm8 + OneByteOpcodes[0x0D] = "or"; // OR EAX, imm32 + // Group 1 instructions (ADD, OR, ADC, SBB, AND, SUB, XOR, CMP) OneByteOpcodes[0x80] = "group1b"; OneByteOpcodes[0x81] = "group1d"; diff --git a/X86DisassemblerTests/OrInstructionTests.cs b/X86DisassemblerTests/OrInstructionTests.cs new file mode 100644 index 0000000..887e05f --- /dev/null +++ b/X86DisassemblerTests/OrInstructionTests.cs @@ -0,0 +1,49 @@ +namespace X86DisassemblerTests; + +using System; +using Xunit; +using X86Disassembler.X86; + +/// +/// Tests for OR instruction handlers +/// +public class OrInstructionTests +{ + /// + /// Tests the OR r8, r/m8 instruction (0x0A) + /// + [Fact] + public void TestOrR8Rm8() + { + // Arrange + byte[] code = { 0x0A, 0xC8 }; // OR CL, AL + + // Act + Disassembler disassembler = new Disassembler(code, 0x1000); + var instructions = disassembler.Disassemble(); + + // Assert + Assert.Single(instructions); + Assert.Equal("or", instructions[0].Mnemonic); + Assert.Equal("cl, al", instructions[0].Operands); + } + + /// + /// Tests the OR r8, m8 instruction (0x0A) with memory operand + /// + [Fact] + public void TestOrR8M8() + { + // Arrange + byte[] code = { 0x0A, 0x00 }; // OR AL, BYTE PTR [EAX] + + // Act + Disassembler disassembler = new Disassembler(code, 0x1000); + var instructions = disassembler.Disassemble(); + + // Assert + Assert.Single(instructions); + Assert.Equal("or", instructions[0].Mnemonic); + Assert.Equal("al, byte ptr [eax]", instructions[0].Operands); + } +}