diff --git a/X86Disassembler/X86/Handlers/ControlFlowHandler.cs b/X86Disassembler/X86/Handlers/ControlFlowHandler.cs
index 96e5fe6..81b0440 100644
--- a/X86Disassembler/X86/Handlers/ControlFlowHandler.cs
+++ b/X86Disassembler/X86/Handlers/ControlFlowHandler.cs
@@ -29,6 +29,22 @@ public class ControlFlowHandler : InstructionHandler
/// 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)
{
@@ -76,6 +92,29 @@ public class ControlFlowHandler : InstructionHandler
/// 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);
@@ -161,7 +200,7 @@ public class ControlFlowHandler : InstructionHandler
Decoder.SetPosition(position + 4);
// Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset);
+ uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction
instruction.Operands = $"0x{targetAddress:X8}";
return true;
@@ -184,7 +223,7 @@ public class ControlFlowHandler : InstructionHandler
Decoder.SetPosition(position + 4);
// Calculate the target address (relative to the next instruction)
- uint targetAddress = (uint)(position + offset);
+ uint targetAddress = (uint)(position + offset + 4); // +4 because the offset is relative to the next instruction
instruction.Operands = $"0x{targetAddress:X8}";
return true;
@@ -236,6 +275,29 @@ public class ControlFlowHandler : InstructionHandler
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
///