diff --git a/X86Disassembler/X86/Handlers/Add/AddR16Rm16Handler.cs b/X86Disassembler/X86/Handlers/Add/AddR16Rm16Handler.cs
new file mode 100644
index 0000000..a96cafc
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Add/AddR16Rm16Handler.cs
@@ -0,0 +1,72 @@
+using X86Disassembler.X86.Operands;
+
+namespace X86Disassembler.X86.Handlers.Add;
+
+///
+/// Handler for ADD r16, r/m16 instruction (opcode 03 with 0x66 prefix)
+///
+public class AddR16Rm16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the AddR16Rm16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public AddR16Rm16Handler(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)
+ {
+ // ADD r16, r/m16 is encoded as 0x03 with 0x66 prefix
+ if (opcode != 0x03)
+ {
+ return false;
+ }
+
+ // Only handle when the operand size prefix is present
+ return Decoder.HasOperandSizePrefix();
+ }
+
+ ///
+ /// Decodes an ADD 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 instruction type
+ instruction.Type = InstructionType.Add;
+
+ // Check if we can read the ModR/M byte
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // For ADD r16, r/m16 (0x03 with 0x66 prefix):
+ // - The reg field of the ModR/M byte specifies the destination register
+ // - The r/m field with mod specifies the source operand (register or memory)
+ var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM16();
+
+ // Note: The operand size is already set to 16-bit by the ReadModRM16 method
+
+ // Create the destination register operand with 16-bit size
+ var destinationOperand = OperandFactory.CreateRegisterOperand(reg, 16);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destinationOperand,
+ sourceOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/Add/AddRm16R16Handler.cs b/X86Disassembler/X86/Handlers/Add/AddRm16R16Handler.cs
new file mode 100644
index 0000000..670f9b4
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/Add/AddRm16R16Handler.cs
@@ -0,0 +1,72 @@
+using X86Disassembler.X86.Operands;
+
+namespace X86Disassembler.X86.Handlers.Add;
+
+///
+/// Handler for ADD r/m16, r16 instruction (opcode 01 with 0x66 prefix)
+///
+public class AddRm16R16Handler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the AddRm16R16Handler class
+ ///
+ /// The instruction decoder that owns this handler
+ public AddRm16R16Handler(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)
+ {
+ // ADD r/m16, r16 is encoded as 0x01 with 0x66 prefix
+ if (opcode != 0x01)
+ {
+ return false;
+ }
+
+ // Only handle when the operand size prefix is present
+ return Decoder.HasOperandSizePrefix();
+ }
+
+ ///
+ /// Decodes an ADD 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 instruction type
+ instruction.Type = InstructionType.Add;
+
+ // Check if we can read the ModR/M byte
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // For ADD r/m16, r16 (0x01 with 0x66 prefix):
+ // - The reg field of the ModR/M byte specifies the source register
+ // - The r/m field with mod specifies the destination operand (register or memory)
+ var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM16();
+
+ // Note: The operand size is already set to 16-bit by the ReadModRM16 method
+
+ // Create the source register operand with 16-bit size
+ var sourceOperand = OperandFactory.CreateRegisterOperand(reg, 16);
+
+ // Set the structured operands
+ instruction.StructuredOperands =
+ [
+ destinationOperand,
+ sourceOperand
+ ];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
index d749d48..0c42183 100644
--- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
+++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
@@ -297,6 +297,10 @@ public class InstructionHandlerFactory
_handlers.Add(new AddRm32R32Handler(_decoder)); // ADD r/m32, r32 (opcode 01)
_handlers.Add(new AddEaxImmHandler(_decoder)); // ADD EAX, imm32 (opcode 05)
+ // Add ADD register-to-register handlers (16-bit)
+ _handlers.Add(new AddR16Rm16Handler(_decoder)); // ADD r16, r/m16 (opcode 03 with 0x66 prefix)
+ _handlers.Add(new AddRm16R16Handler(_decoder)); // ADD r/m16, r16 (opcode 01 with 0x66 prefix)
+
// Add ADD register-to-register handlers (8-bit)
_handlers.Add(new AddRm8R8Handler(_decoder)); // ADD r/m8, r8 (opcode 00)
_handlers.Add(new AddR8Rm8Handler(_decoder)); // ADD r8, r/m8 (opcode 02)
diff --git a/X86DisassemblerTests/TestData/add_tests.csv b/X86DisassemblerTests/TestData/add_tests.csv
index 0e505b8..c5a21bc 100644
--- a/X86DisassemblerTests/TestData/add_tests.csv
+++ b/X86DisassemblerTests/TestData/add_tests.csv
@@ -31,6 +31,6 @@ RawBytes;Instructions
810488AA000000;[{ "Type": "Add", "Operands": ["dword ptr [eax+ecx*4]", "0xAA"] }]
# Mixed addressing modes
-00A314285600;[{ "Type": "Add", "Operands": ["byte ptr [ebx+0x562814]", "ah"] }]
-6601B310203040;[{ "Type": "Add", "Operands": ["si", "word ptr [ebx+0x40302010]"] }]
-030C8D10203040;[{ "Type": "Add", "Operands": ["ecx", "dword ptr [ebp*4+0x40302010]"] }]
\ No newline at end of file
+00A314285600;[{ "Type": "Add", "Operands": ["byte ptr [ebx+0x00562814]", "ah"] }]
+6601B310203040;[{ "Type": "Add", "Operands": ["word ptr [ebx+0x40302010]", "si"] }]
+030C8D10203040;[{ "Type": "Add", "Operands": ["ecx", "dword ptr [ecx*4+0x40302010]"] }]
\ No newline at end of file