From b7c6092b7f46841b4235b9f689efb8ff7b6174f8 Mon Sep 17 00:00:00 2001 From: bird_egop Date: Mon, 14 Apr 2025 00:53:16 +0300 Subject: [PATCH] Simplified TEST instruction handlers by removing special cases and improving code structure --- .../Handlers/Test/TestImmWithRm32Handler.cs | 43 ++++++++-------- .../Handlers/Test/TestImmWithRm8Handler.cs | 50 ++++++++++--------- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/X86Disassembler/X86/Handlers/Test/TestImmWithRm32Handler.cs b/X86Disassembler/X86/Handlers/Test/TestImmWithRm32Handler.cs index 4ccbe86..4f5b81a 100644 --- a/X86Disassembler/X86/Handlers/Test/TestImmWithRm32Handler.cs +++ b/X86Disassembler/X86/Handlers/Test/TestImmWithRm32Handler.cs @@ -24,8 +24,22 @@ public class TestImmWithRm32Handler : InstructionHandler public override bool CanHandle(byte opcode) { // This handler only handles opcode 0xF7 - // The reg field check (for TEST operation) will be done in the Decode method - return opcode == 0xF7; + if (opcode != 0xF7) + { + return false; + } + + // Check if we have enough bytes to read the ModR/M byte + if (!Decoder.CanReadByte()) + { + return false; + } + + // Check if the reg field is 0 (TEST operation) + byte modRM = CodeBuffer[Decoder.GetPosition()]; + byte reg = (byte)((modRM & 0x38) >> 3); + + return reg == 0; // 0 = TEST } /// @@ -36,39 +50,24 @@ public class TestImmWithRm32Handler : InstructionHandler /// True if the instruction was successfully decoded public override bool Decode(byte opcode, Instruction instruction) { - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - // Read the ModR/M byte - var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); - - // Check if the reg field is 0 (TEST operation) - if (reg != 0) - { - return false; // Not a TEST instruction - } - // Set the mnemonic instruction.Mnemonic = "test"; - + + // Read the ModR/M byte + var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); + // For direct register addressing (mod == 3), the r/m field specifies a register if (mod == 3) { destOperand = ModRMDecoder.GetRegisterName(rm, 32); } - position = Decoder.GetPosition(); // Read the immediate value - if (position + 3 >= Length) + if (!Decoder.CanReadUInt()) { return false; } - // Read the immediate value uint imm32 = Decoder.ReadUInt32(); // Set the operands diff --git a/X86Disassembler/X86/Handlers/Test/TestImmWithRm8Handler.cs b/X86Disassembler/X86/Handlers/Test/TestImmWithRm8Handler.cs index cf7875b..884173a 100644 --- a/X86Disassembler/X86/Handlers/Test/TestImmWithRm8Handler.cs +++ b/X86Disassembler/X86/Handlers/Test/TestImmWithRm8Handler.cs @@ -24,8 +24,22 @@ public class TestImmWithRm8Handler : InstructionHandler public override bool CanHandle(byte opcode) { // This handler only handles opcode 0xF6 - // The reg field check (for TEST operation) will be done in the Decode method - return opcode == 0xF6; + if (opcode != 0xF6) + { + return false; + } + + // Check if we have enough bytes to read the ModR/M byte + if (!Decoder.CanReadByte()) + { + return false; + } + + // Check if the reg field is 0 (TEST operation) + byte modRM = CodeBuffer[Decoder.GetPosition()]; + byte reg = (byte)((modRM & 0x38) >> 3); + + return reg == 0; // 0 = TEST } /// @@ -36,38 +50,26 @@ public class TestImmWithRm8Handler : InstructionHandler /// True if the instruction was successfully decoded public override bool Decode(byte opcode, Instruction instruction) { - int position = Decoder.GetPosition(); - - if (position >= Length) - { - return false; - } - - // Read the ModR/M byte - var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(true); - - // Check if the reg field is 0 (TEST operation) - if (reg != RegisterIndex.A) - { - return false; // Not a TEST instruction - } - // Set the mnemonic instruction.Mnemonic = "test"; - - // For direct register addressing (mod == 3), the r/m field specifies a register - if (mod == 3) + + // Read the ModR/M byte + var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); + + // Get the destination operand based on addressing mode + if (mod == 3) // Register operand { + // For direct register addressing, use the correct 8-bit register name destOperand = ModRMDecoder.GetRegisterName(rm, 8); } - // Use the ModR/M decoder for memory addressing - // Read the immediate value - if (position >= Length) + // Check if we have enough bytes for the immediate value + if (!Decoder.CanReadByte()) { return false; } + // Read the immediate value byte imm8 = Decoder.ReadByte(); // Set the operands