diff --git a/.windsurfrules b/.windsurfrules
index bc3de2d..78aed38 100644
--- a/.windsurfrules
+++ b/.windsurfrules
@@ -16,4 +16,6 @@ never use terminal commands to edit code. In case of a failure, write it to user
never address compiler warnings yourself. If you see a warning, suggest to address it.
-when working with RVA variables, always add that to variable name, e.g. "nameRVA".
\ No newline at end of file
+when working with RVA variables, always add that to variable name, e.g. "nameRVA".
+
+always build only affected project, not full solution.
\ No newline at end of file
diff --git a/X86Disassembler/X86/Handlers/ArithmeticHandler.cs b/X86Disassembler/X86/Handlers/ArithmeticHandler.cs
deleted file mode 100644
index f4e545e..0000000
--- a/X86Disassembler/X86/Handlers/ArithmeticHandler.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-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/Handlers/ControlFlowHandler.cs b/X86Disassembler/X86/Handlers/ControlFlowHandler.cs
deleted file mode 100644
index 81b0440..0000000
--- a/X86Disassembler/X86/Handlers/ControlFlowHandler.cs
+++ /dev/null
@@ -1,343 +0,0 @@
-namespace X86Disassembler.X86.Handlers;
-
-///
-/// Handler for control flow instructions (JMP, CALL, RET, etc.)
-///
-public class ControlFlowHandler : InstructionHandler
-{
- // Condition codes for conditional jumps
- private static readonly string[] ConditionCodes = {
- "o", "no", "b", "ae", "e", "ne", "be", "a",
- "s", "ns", "p", "np", "l", "ge", "le", "g"
- };
-
- ///
- /// Initializes a new instance of the ControlFlowHandler class
- ///
- /// The buffer containing the code to decode
- /// The instruction decoder that owns this handler
- /// The length of the buffer
- public ControlFlowHandler(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)
- {
- // Two-byte opcodes (0F prefix)
- if (opcode == 0x0F)
- {
- int position = Decoder.GetPosition();
- if (position < Length)
- {
- byte secondByte = CodeBuffer[position];
- // Two-byte conditional jumps (0F 80-0F 8F)
- if (secondByte >= 0x80 && secondByte <= 0x8F)
- {
- return true;
- }
- }
- return false;
- }
-
- // RET instruction
- if (opcode == 0xC3 || opcode == 0xC2)
- {
- return true;
- }
-
- // CALL instruction
- if (opcode == 0xE8)
- {
- return true;
- }
-
- // JMP instructions
- if (opcode == 0xE9 || opcode == 0xEB)
- {
- return true;
- }
-
- // Conditional jumps
- if (opcode >= 0x70 && opcode <= 0x7F)
- {
- return true;
- }
-
- // INT instructions
- if (opcode == 0xCC || opcode == 0xCD)
- {
- return true;
- }
-
- // JECXZ instruction
- if (opcode == 0xE3)
- {
- return true;
- }
-
- return false;
- }
-
- ///
- /// Decodes a control flow 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)
- {
- // Handle two-byte opcodes (0F prefix)
- if (opcode == 0x0F)
- {
- int position = Decoder.GetPosition();
- if (position < Length)
- {
- byte secondByte = CodeBuffer[position];
- Decoder.SetPosition(position + 1);
-
- // Two-byte conditional jumps (0F 80-0F 8F)
- if (secondByte >= 0x80 && secondByte <= 0x8F)
- {
- // Set mnemonic (j + condition code)
- int condIndex = secondByte - 0x80;
- instruction.Mnemonic = "j" + ConditionCodes[condIndex];
-
- // Decode 32-bit relative jump
- return DecodeTwoByteConditionalJump(instruction);
- }
- }
- return false;
- }
-
- // Set the mnemonic based on the opcode
- instruction.Mnemonic = OpcodeMap.GetMnemonic(opcode);
-
- // Handle different types of control flow instructions
- if (opcode == 0xC3) // RET
- {
- // No operands for RET
- instruction.Operands = string.Empty;
- return true;
- }
- else if (opcode == 0xC2) // RET imm16
- {
- return DecodeRETImm16(instruction);
- }
- else if (opcode == 0xE8) // CALL rel32
- {
- return DecodeCALLRel32(instruction);
- }
- else if (opcode == 0xE9) // JMP rel32
- {
- return DecodeJMPRel32(instruction);
- }
- else if (opcode == 0xEB) // JMP rel8
- {
- return DecodeJMPRel8(instruction);
- }
- else if (opcode >= 0x70 && opcode <= 0x7F) // Conditional jumps
- {
- return DecodeConditionalJump(opcode, instruction);
- }
- else if (opcode == 0xCC) // INT3
- {
- // No operands for INT3
- instruction.Operands = string.Empty;
- return true;
- }
- else if (opcode == 0xCD) // INT imm8
- {
- return DecodeINTImm8(instruction);
- }
- else if (opcode == 0xE3) // JECXZ rel8
- {
- return DecodeJECXZRel8(instruction);
- }
-
- return false;
- }
-
- ///
- /// Decodes a RET instruction with 16-bit immediate operand
- ///
- private bool DecodeRETImm16(Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position + 2 > Length)
- {
- return false;
- }
-
- // Read the immediate value
- ushort imm16 = BitConverter.ToUInt16(CodeBuffer, position);
- Decoder.SetPosition(position + 2);
-
- instruction.Operands = $"0x{imm16:X4}";
- return true;
- }
-
- ///
- /// Decodes a CALL instruction with 32-bit relative offset
- ///
- private bool DecodeCALLRel32(Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position + 4 > Length)
- {
- return false;
- }
-
- // Read the relative offset
- int offset = BitConverter.ToInt32(CodeBuffer, position);
- Decoder.SetPosition(position + 4);
-
- // Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction
-
- instruction.Operands = $"0x{targetAddress:X8}";
- return true;
- }
-
- ///
- /// Decodes a JMP instruction with 32-bit relative offset
- ///
- private bool DecodeJMPRel32(Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position + 4 > Length)
- {
- return false;
- }
-
- // Read the relative offset
- int offset = BitConverter.ToInt32(CodeBuffer, position);
- Decoder.SetPosition(position + 4);
-
- // Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction
-
- instruction.Operands = $"0x{targetAddress:X8}";
- return true;
- }
-
- ///
- /// Decodes a JMP instruction with 8-bit relative offset
- ///
- private bool DecodeJMPRel8(Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position >= Length)
- {
- return false;
- }
-
- // Read the relative offset
- sbyte offset = (sbyte)CodeBuffer[position];
- Decoder.SetPosition(position + 1);
-
- // Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset + 1); // +1 because the offset is relative to the next instruction
-
- instruction.Operands = $"0x{targetAddress:X8}";
- return true;
- }
-
- ///
- /// Decodes a conditional jump instruction
- ///
- private bool DecodeConditionalJump(byte opcode, Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position >= Length)
- {
- return false;
- }
-
- // Read the relative offset
- sbyte offset = (sbyte)CodeBuffer[position];
- Decoder.SetPosition(position + 1);
-
- // Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset + 1); // +1 because the offset is relative to the next instruction
-
- instruction.Operands = $"0x{targetAddress:X8}";
- return true;
- }
-
- ///
- /// Decodes a two-byte conditional jump instruction with 32-bit relative offset
- ///
- private bool DecodeTwoByteConditionalJump(Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position + 4 > Length)
- {
- return false;
- }
-
- // Read the relative offset
- int offset = BitConverter.ToInt32(CodeBuffer, position);
- Decoder.SetPosition(position + 4);
-
- // Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction
-
- instruction.Operands = $"0x{targetAddress:X8}";
- return true;
- }
-
- ///
- /// Decodes an INT instruction with 8-bit immediate operand
- ///
- private bool DecodeINTImm8(Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position >= Length)
- {
- return false;
- }
-
- // Read the immediate value
- byte imm8 = CodeBuffer[position];
- Decoder.SetPosition(position + 1);
-
- instruction.Operands = $"0x{imm8:X2}";
- return true;
- }
-
- ///
- /// Decodes a JECXZ instruction with 8-bit relative offset
- ///
- private bool DecodeJECXZRel8(Instruction instruction)
- {
- int position = Decoder.GetPosition();
-
- if (position >= Length)
- {
- return false;
- }
-
- // Read the relative offset
- sbyte offset = (sbyte)CodeBuffer[position];
- Decoder.SetPosition(position + 1);
-
- // Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset + 1); // +1 because the offset is relative to the next instruction
-
- instruction.Operands = $"0x{targetAddress:X8}";
- return true;
- }
-}
diff --git a/X86Disassembler/X86/Handlers/TestHandler.cs b/X86Disassembler/X86/Handlers/TestHandler.cs
deleted file mode 100644
index 37b22f3..0000000
--- a/X86Disassembler/X86/Handlers/TestHandler.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-namespace X86Disassembler.X86.Handlers;
-
-///
-/// Handler for TEST instructions
-///
-public class TestHandler : InstructionHandler
-{
- ///
- /// Initializes a new instance of the TestHandler class
- ///
- /// The buffer containing the code to decode
- /// The instruction decoder that owns this handler
- /// The length of the buffer
- public TestHandler(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 == 0x84 || opcode == 0x85 || opcode == 0xA8 || opcode == 0xA9;
- }
-
- ///
- /// Decodes a TEST 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;
- }
-
- // Set the mnemonic
- instruction.Mnemonic = "test";
-
- switch (opcode)
- {
- case 0x84: // TEST r/m8, r8
- case 0x85: // TEST r/m32, r32
- // Read the ModR/M byte
- var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM();
-
- // Determine the source register
- string sourceReg;
- if (opcode == 0x84) // 8-bit registers
- {
- sourceReg = ModRMDecoder.GetRegister8(reg);
- }
- else // 32-bit registers
- {
- sourceReg = ModRMDecoder.GetRegister32(reg);
- }
-
- // Set the operands
- instruction.Operands = $"{destOperand}, {sourceReg}";
- break;
-
- case 0xA8: // TEST AL, imm8
- if (position < Length)
- {
- byte imm8 = CodeBuffer[position];
- Decoder.SetPosition(position + 1);
- instruction.Operands = $"al, 0x{imm8:X2}";
- }
- else
- {
- instruction.Operands = "al, ???";
- }
- break;
-
- case 0xA9: // TEST EAX, imm32
- if (position + 3 < Length)
- {
- uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
- Decoder.SetPosition(position + 4);
- instruction.Operands = $"eax, 0x{imm32:X8}";
- }
- else
- {
- instruction.Operands = "eax, ???";
- }
- break;
-
- default:
- return false;
- }
-
- return true;
- }
-}