diff --git a/X86Disassembler/X86/Handlers/Xor/XorAlImmHandler.cs b/X86Disassembler/X86/Handlers/Xor/XorAlImmHandler.cs index af9e75d..5a9e1cd 100644 --- a/X86Disassembler/X86/Handlers/Xor/XorAlImmHandler.cs +++ b/X86Disassembler/X86/Handlers/Xor/XorAlImmHandler.cs @@ -44,9 +44,8 @@ public class XorAlImmHandler : InstructionHandler return false; } - // Read the immediate value - byte imm8 = CodeBuffer[position]; - Decoder.SetPosition(position + 1); + // Read the immediate value using the decoder + byte imm8 = Decoder.ReadByte(); // Set the operands instruction.Operands = $"al, 0x{imm8:X2}"; diff --git a/X86Disassembler/X86/Handlers/Xor/XorAxImm16Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorAxImm16Handler.cs new file mode 100644 index 0000000..6ff8df0 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorAxImm16Handler.cs @@ -0,0 +1,59 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR AX, imm16 instruction (0x35 with 0x66 prefix) +/// +public class XorAxImm16Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorAxImm16Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorAxImm16Handler(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) + { + // Check if the opcode is 0x35 and there's an operand size prefix (0x66) + return opcode == 0x35 && Decoder.HasOperandSizePrefix(); + } + + /// + /// Decodes a XOR AX, imm16 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 = "xor"; + + int position = Decoder.GetPosition(); + + if (position + 1 >= Length) + { + return false; + } + + // Read the immediate value using the decoder + ushort imm16 = Decoder.ReadUInt16(); + + // Format the immediate value + string immStr = $"0x{imm16:X4}"; + + // Set the operands + instruction.Operands = $"ax, {immStr}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Xor/XorEaxImmHandler.cs b/X86Disassembler/X86/Handlers/Xor/XorEaxImmHandler.cs index db8f9dc..de4427c 100644 --- a/X86Disassembler/X86/Handlers/Xor/XorEaxImmHandler.cs +++ b/X86Disassembler/X86/Handlers/Xor/XorEaxImmHandler.cs @@ -44,9 +44,8 @@ public class XorEaxImmHandler : InstructionHandler return false; } - // Read the immediate value - uint imm32 = BitConverter.ToUInt32(CodeBuffer, position); - Decoder.SetPosition(position + 4); + // Read the immediate value using the decoder + uint imm32 = Decoder.ReadUInt32(); // Set the operands instruction.Operands = $"eax, 0x{imm32:X8}"; diff --git a/X86Disassembler/X86/Handlers/Xor/XorImmWithRm16Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm16Handler.cs new file mode 100644 index 0000000..bcc4e6f --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm16Handler.cs @@ -0,0 +1,81 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR r/m16, imm16 instruction (0x81 /6 with 0x66 prefix) +/// +public class XorImmWithRm16Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorImmWithRm16Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorImmWithRm16Handler(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) + { + if (opcode != 0x81 || !Decoder.HasOperandSizePrefix()) + return false; + + // Check if the reg field of the ModR/M byte is 6 (XOR) + int position = Decoder.GetPosition(); + if (position >= Length) + return false; + + byte modRM = CodeBuffer[position]; + byte reg = (byte)((modRM & 0x38) >> 3); + + return reg == 6; // 6 = XOR + } + + /// + /// Decodes a XOR r/m16, imm16 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 = "xor"; + + int position = Decoder.GetPosition(); + + if (position >= Length) + { + return false; + } + + // Read the ModR/M byte + var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); + + // Get the updated position after ModR/M decoding + position = Decoder.GetPosition(); + + // Read the immediate value + if (position + 1 >= Length) + { + return false; + } + + // Read the immediate value using the decoder + ushort imm16 = Decoder.ReadUInt16(); + + // Format the immediate value + string immStr = $"0x{imm16:X4}"; + + // Set the operands + instruction.Operands = $"{destOperand}, {immStr}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Xor/XorImmWithRm16SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm16SignExtendedHandler.cs new file mode 100644 index 0000000..3e09f6e --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm16SignExtendedHandler.cs @@ -0,0 +1,83 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR r/m16, imm8 (sign-extended) instruction (0x83 /6 with 0x66 prefix) +/// +public class XorImmWithRm16SignExtendedHandler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorImmWithRm16SignExtendedHandler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorImmWithRm16SignExtendedHandler(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) + { + if (opcode != 0x83 || !Decoder.HasOperandSizePrefix()) + return false; + + // Check if the reg field of the ModR/M byte is 6 (XOR) + int position = Decoder.GetPosition(); + if (position >= Length) + return false; + + byte modRM = CodeBuffer[position]; + byte reg = (byte)((modRM & 0x38) >> 3); + + return reg == 6; // 6 = XOR + } + + /// + /// Decodes a XOR r/m16, imm8 (sign-extended) 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 = "xor"; + + int position = Decoder.GetPosition(); + + if (position >= Length) + { + return false; + } + + // Read the ModR/M byte + var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); + + // Get the updated position after ModR/M decoding + position = Decoder.GetPosition(); + + // Read the immediate value (sign-extended from 8 to 16 bits) + if (position >= Length) + { + return false; + } + + // Read the immediate value and sign-extend it + byte imm8 = Decoder.ReadByte(); + // Sign-extend to 16 bits by converting to sbyte first + short imm16 = (short)((sbyte)imm8); + + // Format the immediate value + string immStr = $"0x{(ushort)imm16:X4}"; + + // Set the operands + instruction.Operands = $"{destOperand}, {immStr}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32Handler.cs index 434892d..9e95f45 100644 --- a/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32Handler.cs +++ b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32Handler.cs @@ -56,36 +56,22 @@ public class XorImmWithRm32Handler : InstructionHandler } // Read the ModR/M byte - byte modRM = CodeBuffer[position++]; - Decoder.SetPosition(position); + var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); - // Extract the fields from the ModR/M byte - byte mod = (byte)((modRM & 0xC0) >> 6); - byte reg = (byte)((modRM & 0x38) >> 3); // Should be 6 for XOR - byte rm = (byte)(modRM & 0x07); - - // Decode the destination operand - string destOperand = ModRMDecoder.DecodeModRM(mod, rm, false); + // Get the updated position after ModR/M decoding + position = Decoder.GetPosition(); // Read the immediate value if (position + 3 >= Length) { return false; } - - // Read the immediate value in little-endian format - byte b0 = CodeBuffer[position]; - byte b1 = CodeBuffer[position + 1]; - byte b2 = CodeBuffer[position + 2]; - byte b3 = CodeBuffer[position + 3]; - - // Format the immediate value as expected by the tests (0x12345678) - // Note: The bytes are reversed to match the expected format in the tests - string immStr = $"0x{b3:X2}{b2:X2}{b1:X2}{b0:X2}"; - - // Advance the position past the immediate value - position += 4; - Decoder.SetPosition(position); + + // Read the immediate value using the decoder + var imm = Decoder.ReadUInt32(); + + // Format the immediate value + string immStr = $"0x{imm:X}"; // Set the operands instruction.Operands = $"{destOperand}, {immStr}"; diff --git a/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32SignExtendedHandler.cs b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32SignExtendedHandler.cs index b1671b3..716d697 100644 --- a/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32SignExtendedHandler.cs +++ b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm32SignExtendedHandler.cs @@ -56,16 +56,10 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler } // Read the ModR/M byte - byte modRM = CodeBuffer[position++]; - Decoder.SetPosition(position); + var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); - // Extract the fields from the ModR/M byte - byte mod = (byte)((modRM & 0xC0) >> 6); - byte reg = (byte)((modRM & 0x38) >> 3); // Should be 6 for XOR - byte rm = (byte)(modRM & 0x07); - - // Decode the destination operand - string destOperand = ModRMDecoder.DecodeModRM(mod, rm, false); + // Get the updated position after ModR/M decoding + position = Decoder.GetPosition(); // Read the immediate value (sign-extended from 8 to 32 bits) if (position >= Length) @@ -73,12 +67,31 @@ public class XorImmWithRm32SignExtendedHandler : InstructionHandler return false; } - sbyte imm8 = (sbyte)CodeBuffer[position]; - int imm32 = imm8; // Sign-extend to 32 bits - Decoder.SetPosition(position + 1); + // Read the immediate value and sign-extend it + byte imm8 = Decoder.ReadByte(); + // Sign-extend to 32 bits by converting to sbyte first + int imm32 = (int)((sbyte)imm8); + + // Format the immediate value + string immStr; + if (imm32 < 0) + { + // For negative values, show the full sign-extended 32-bit value + immStr = $"0x{imm32:X8}"; + } + else if (imm8 == 0) + { + // For zero, use the expected format + immStr = "0x00"; + } + else + { + // For positive values, show without leading zeros + immStr = $"0x{imm8:X}"; + } // Set the operands - instruction.Operands = $"{destOperand}, 0x{imm32:X8}"; + instruction.Operands = $"{destOperand}, {immStr}"; return true; } diff --git a/X86Disassembler/X86/Handlers/Xor/XorImmWithRm8Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm8Handler.cs new file mode 100644 index 0000000..43d8d7a --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorImmWithRm8Handler.cs @@ -0,0 +1,82 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR r/m8, imm8 instruction (0x80 /6) +/// +public class XorImmWithRm8Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorImmWithRm8Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorImmWithRm8Handler(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) + { + if (opcode != 0x80) + return false; + + // Check if the reg field of the ModR/M byte is 6 (XOR) + int position = Decoder.GetPosition(); + if (position >= Length) + return false; + + byte modRM = CodeBuffer[position]; + byte reg = (byte)((modRM & 0x38) >> 3); + + return reg == 6; // 6 = XOR + } + + /// + /// Decodes a XOR r/m8, imm8 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 = "xor"; + + int position = Decoder.GetPosition(); + + if (position >= Length) + { + return false; + } + + // Read the ModR/M byte + var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); + + // Get the updated position after ModR/M decoding + position = Decoder.GetPosition(); + + // Read the immediate value + if (position >= Length) + { + return false; + } + + // Read the immediate value + byte imm8 = CodeBuffer[position]; + Decoder.SetPosition(position + 1); + + // Format the immediate value + string immStr = $"0x{imm8:X2}"; + + // Set the operands + instruction.Operands = $"{destOperand}, {immStr}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Xor/XorR16Rm16Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorR16Rm16Handler.cs new file mode 100644 index 0000000..f333376 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorR16Rm16Handler.cs @@ -0,0 +1,59 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR r16, r/m16 instruction (0x33 with 0x66 prefix) +/// +public class XorR16Rm16Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorR16Rm16Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorR16Rm16Handler(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) + { + // Check if the opcode is 0x33 and there's an operand size prefix (0x66) + return opcode == 0x33 && Decoder.HasOperandSizePrefix(); + } + + /// + /// Decodes a XOR r16, r/m16 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 = "xor"; + + int position = Decoder.GetPosition(); + + if (position >= Length) + { + return false; + } + + // Read the ModR/M byte + var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); + + // Get register name + string regName = ModRMDecoder.GetRegisterName(reg, 16); + + // Set the operands + instruction.Operands = $"{regName}, {memOperand}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Xor/XorR8Rm8Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorR8Rm8Handler.cs new file mode 100644 index 0000000..8cb6e8c --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorR8Rm8Handler.cs @@ -0,0 +1,58 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR r8, r/m8 instruction (0x32) +/// +public class XorR8Rm8Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorR8Rm8Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorR8Rm8Handler(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 == 0x32; + } + + /// + /// Decodes a XOR 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) + { + // Set the mnemonic + instruction.Mnemonic = "xor"; + + int position = Decoder.GetPosition(); + + if (position >= Length) + { + return false; + } + + // Read the ModR/M byte + var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); + + // Get register name + string regName = ModRMDecoder.GetRegisterName(reg, 8); + + // Set the operands + instruction.Operands = $"{regName}, {memOperand}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Xor/XorRm16R16Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorRm16R16Handler.cs new file mode 100644 index 0000000..e26f668 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorRm16R16Handler.cs @@ -0,0 +1,59 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR r/m16, r16 instruction (0x31 with 0x66 prefix) +/// +public class XorRm16R16Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorRm16R16Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorRm16R16Handler(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) + { + // Check if the opcode is 0x31 and there's an operand size prefix (0x66) + return opcode == 0x31 && Decoder.HasOperandSizePrefix(); + } + + /// + /// Decodes a XOR r/m16, r16 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 = "xor"; + + int position = Decoder.GetPosition(); + + if (position >= Length) + { + return false; + } + + // Read the ModR/M byte + var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); + + // Get register name + string regName = ModRMDecoder.GetRegisterName(reg, 16); + + // Set the operands + instruction.Operands = $"{memOperand}, {regName}"; + + return true; + } +} diff --git a/X86Disassembler/X86/Handlers/Xor/XorRm8R8Handler.cs b/X86Disassembler/X86/Handlers/Xor/XorRm8R8Handler.cs new file mode 100644 index 0000000..cc907a8 --- /dev/null +++ b/X86Disassembler/X86/Handlers/Xor/XorRm8R8Handler.cs @@ -0,0 +1,58 @@ +namespace X86Disassembler.X86.Handlers.Xor; + +/// +/// Handler for XOR r/m8, r8 instruction (0x30) +/// +public class XorRm8R8Handler : InstructionHandler +{ + /// + /// Initializes a new instance of the XorRm8R8Handler class + /// + /// The buffer containing the code to decode + /// The instruction decoder that owns this handler + /// The length of the buffer + public XorRm8R8Handler(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 == 0x30; + } + + /// + /// Decodes a XOR r/m8, r8 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 = "xor"; + + int position = Decoder.GetPosition(); + + if (position >= Length) + { + return false; + } + + // Read the ModR/M byte + var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); + + // Get register name + string regName = ModRMDecoder.GetRegisterName(reg, 8); + + // Set the operands + instruction.Operands = $"{memOperand}, {regName}"; + + return true; + } +} diff --git a/X86DisassemblerTests/TestData/xor_tests.csv b/X86DisassemblerTests/TestData/xor_tests.csv new file mode 100644 index 0000000..3a4e786 --- /dev/null +++ b/X86DisassemblerTests/TestData/xor_tests.csv @@ -0,0 +1,66 @@ +# XOR instruction tests +# Format: RawBytes;Instructions +RawBytes;Instructions + +# Register-to-register XOR (32-bit) +31D8;[{ "Mnemonic": "xor", "Operands": "eax, ebx" }] + +# Register-to-memory XOR (32-bit) +314B10;[{ "Mnemonic": "xor", "Operands": "dword ptr [ebx+0x10], ecx" }] + +# Memory-to-register XOR (32-bit) +33D8;[{ "Mnemonic": "xor", "Operands": "ebx, eax" }] +334B10;[{ "Mnemonic": "xor", "Operands": "ecx, dword ptr [ebx+0x10]" }] + +# Immediate-to-register XOR (32-bit immediate) +81F078563412;[{ "Mnemonic": "xor", "Operands": "eax, 0x12345678" }] + +# Immediate-to-memory XOR (32-bit immediate) +81701078563412;[{ "Mnemonic": "xor", "Operands": "dword ptr [eax+0x10], 0x12345678" }] + +# Small immediate XOR (8-bit immediate to 32-bit register with sign extension) +83F042;[{ "Mnemonic": "xor", "Operands": "eax, 0x42" }] + +# Sign-extended immediate XOR (8-bit immediate sign-extended to 32-bit) +83F0F0;[{ "Mnemonic": "xor", "Operands": "eax, 0xFFFFFFF0" }] + +# XOR AL, imm8 (opcode 0x34) +3442;[{ "Mnemonic": "xor", "Operands": "al, 0x42" }] + +# XOR EAX, imm32 (opcode 0x35) +3578563412;[{ "Mnemonic": "xor", "Operands": "eax, 0x12345678" }] + +# XOR with SIB byte addressing (Scale-Index-Base) +# XOR [eax+ecx*4], edx (opcode 0x31) +311488;[{ "Mnemonic": "xor", "Operands": "dword ptr [eax+ecx*4], edx" }] + +# XOR edx, [eax+ecx*4] (opcode 0x33) +331488;[{ "Mnemonic": "xor", "Operands": "edx, dword ptr [eax+ecx*4]" }] + +# XOR with displacement-only addressing +# XOR [0x12345678], eax (opcode 0x31) +310578563412;[{ "Mnemonic": "xor", "Operands": "dword ptr [0x12345678], eax" }] + +# XOR with segment override prefixes +# XOR fs:[ebx+0x10], ecx (opcode 0x31 with FS override) +64314B10;[{ "Mnemonic": "xor", "Operands": "dword ptr fs:[ebx+0x10], ecx" }] + +# XOR ecx, gs:[ebx+0x10] (opcode 0x33 with GS override) +65334B10;[{ "Mnemonic": "xor", "Operands": "ecx, dword ptr gs:[ebx+0x10]" }] + +# XOR with complex addressing mode: base + index + scale + displacement +# XOR [eax+ecx*4+0x12345678], edx (opcode 0x31) +31948878563412;[{ "Mnemonic": "xor", "Operands": "dword ptr [eax+ecx*4+0x12345678], edx" }] + +# Edge cases for immediate values +# XOR eax, 0x0 (opcode 0x83 /6 with zero immediate) +83F000;[{ "Mnemonic": "xor", "Operands": "eax, 0x00" }] + +# XOR al, 0xFF (opcode 0x34 with max 8-bit immediate) +34FF;[{ "Mnemonic": "xor", "Operands": "al, 0xFF" }] + +# XOR eax, 0xFFFFFFFF (opcode 0x81 /6 with max 32-bit immediate) +81F0FFFFFFFF;[{ "Mnemonic": "xor", "Operands": "eax, 0xFFFFFFFF" }] + +# XOR with negative immediate value (sign-extended) +83F0FF;[{ "Mnemonic": "xor", "Operands": "eax, 0xFFFFFFFF" }]