diff --git a/X86Disassembler/X86/Handlers/ArithmeticHandler.cs b/X86Disassembler/X86/Handlers/ArithmeticHandler.cs
new file mode 100644
index 0000000..f4e545e
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/ArithmeticHandler.cs
@@ -0,0 +1,126 @@
+namespace X86Disassembler.X86.Handlers;
+
+///
+/// Handler for arithmetic and logical instructions (ADD, SUB, AND, OR, XOR, etc.)
+///
+public class ArithmeticHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the ArithmeticHandler class
+ ///
+ /// The buffer containing the code to decode
+ /// The instruction decoder that owns this handler
+ /// The length of the buffer
+ public ArithmeticHandler(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)
+ {
+ // XOR instructions
+ if (opcode >= 0x30 && opcode <= 0x35)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Decodes an arithmetic or logical 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 based on the opcode
+ instruction.Mnemonic = OpcodeMap.GetMnemonic(opcode);
+
+ int position = Decoder.GetPosition();
+
+ if (position >= Length)
+ {
+ return false;
+ }
+
+ switch (opcode)
+ {
+ case 0x30: // XOR r/m8, r8
+ case 0x31: // XOR r/m32, r32
+ {
+ // Read the ModR/M byte
+ var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
+
+ // Determine the source register
+ string sourceReg;
+ if (opcode == 0x30) // 8-bit registers
+ {
+ sourceReg = ModRMDecoder.GetRegister8(reg);
+ }
+ else // 32-bit registers
+ {
+ sourceReg = ModRMDecoder.GetRegister32(reg);
+ }
+
+ // Set the operands
+ instruction.Operands = $"{destOperand}, {sourceReg}";
+ return true;
+ }
+
+ case 0x32: // XOR r8, r/m8
+ case 0x33: // XOR r32, r/m32
+ {
+ // Read the ModR/M byte
+ var (mod, reg, rm, srcOperand) = ModRMDecoder.ReadModRM();
+
+ // Determine the destination register
+ string destReg;
+ if (opcode == 0x32) // 8-bit registers
+ {
+ destReg = ModRMDecoder.GetRegister8(reg);
+ }
+ else // 32-bit registers
+ {
+ destReg = ModRMDecoder.GetRegister32(reg);
+ }
+
+ // Set the operands
+ instruction.Operands = $"{destReg}, {srcOperand}";
+ return true;
+ }
+
+ case 0x34: // XOR AL, imm8
+ {
+ if (position < Length)
+ {
+ byte imm8 = CodeBuffer[position];
+ Decoder.SetPosition(position + 1);
+ instruction.Operands = $"al, 0x{imm8:X2}";
+ return true;
+ }
+ break;
+ }
+
+ case 0x35: // XOR EAX, imm32
+ {
+ if (position + 3 < Length)
+ {
+ uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
+ Decoder.SetPosition(position + 4);
+ instruction.Operands = $"eax, 0x{imm32:X8}";
+ return true;
+ }
+ break;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/X86Disassembler/X86/InstructionDecoder.cs b/X86Disassembler/X86/InstructionDecoder.cs
index f95c21e..e91a948 100644
--- a/X86Disassembler/X86/InstructionDecoder.cs
+++ b/X86Disassembler/X86/InstructionDecoder.cs
@@ -50,7 +50,8 @@ public class InstructionDecoder
new DataTransferHandler(_codeBuffer, this, _length),
new ControlFlowHandler(_codeBuffer, this, _length),
new Group3Handler(_codeBuffer, this, _length),
- new TestHandler(_codeBuffer, this, _length)
+ new TestHandler(_codeBuffer, this, _length),
+ new ArithmeticHandler(_codeBuffer, this, _length)
};
}
diff --git a/X86Disassembler/X86/OpcodeMap.cs b/X86Disassembler/X86/OpcodeMap.cs
index bad0108..743c07e 100644
--- a/X86Disassembler/X86/OpcodeMap.cs
+++ b/X86Disassembler/X86/OpcodeMap.cs
@@ -118,6 +118,14 @@ public class OpcodeMap
OneByteOpcodes[0x6A] = "push"; // PUSH imm8
OneByteOpcodes[0xCD] = "int"; // INT imm8
OneByteOpcodes[0xE3] = "jecxz"; // JECXZ rel8
+
+ // XOR instructions
+ OneByteOpcodes[0x30] = "xor"; // XOR r/m8, r8
+ OneByteOpcodes[0x31] = "xor"; // XOR r/m32, r32
+ OneByteOpcodes[0x32] = "xor"; // XOR r8, r/m8
+ OneByteOpcodes[0x33] = "xor"; // XOR r32, r/m32
+ OneByteOpcodes[0x34] = "xor"; // XOR AL, imm8
+ OneByteOpcodes[0x35] = "xor"; // XOR EAX, imm32
}
///