0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-06-21 00:28:36 +03:00

Fixed TEST instruction handlers and tests. Updated TestImmWithRm8Handler and TestImmWithRm32Handler to properly check opcode in CanHandle and validate reg field in Decode. Improved test cases to use InstructionDecoder directly.

This commit is contained in:
bird_egop
2025-04-12 21:21:03 +03:00
parent bf5fcdd2ff
commit fe0b04f5a1
10 changed files with 330 additions and 74 deletions

View File

@ -23,18 +23,9 @@ public class TestImmWithRm32Handler : Group3BaseHandler
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
if (opcode != 0xF7)
return false;
// Check if the reg field of the ModR/M byte is 0 (TEST)
int position = Decoder.GetPosition();
if (position >= Length)
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 0; // 0 = TEST
// This handler only handles opcode 0xF7
// The reg field check (for TEST operation) will be done in the Decode method
return opcode == 0xF7;
}
/// <summary>
@ -45,9 +36,6 @@ public class TestImmWithRm32Handler : Group3BaseHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
// Set the mnemonic
instruction.Mnemonic = "test";
int position = Decoder.GetPosition();
if (position >= Length)
@ -57,15 +45,36 @@ public class TestImmWithRm32Handler : Group3BaseHandler
// Read the ModR/M byte
byte modRM = CodeBuffer[position++];
Decoder.SetPosition(position);
// Extract the fields from the ModR/M byte
byte mod = (byte)((modRM & 0xC0) >> 6);
byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for TEST
byte rm = (byte)(modRM & 0x07);
// Decode the destination operand
string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
// Check if the reg field is 0 (TEST operation)
if (reg != 0)
{
return false; // Not a TEST instruction
}
// Set the mnemonic
instruction.Mnemonic = "test";
Decoder.SetPosition(position);
// Get the operand based on the addressing mode
string destOperand;
// For direct register addressing (mod == 3), the r/m field specifies a register
if (mod == 3)
{
destOperand = GetRegister32(rm);
}
else
{
// Use the ModR/M decoder for memory addressing
destOperand = _modRMDecoder.DecodeModRM(mod, rm, false);
}
// Read the immediate value
if (position + 3 >= Length)
@ -73,6 +82,7 @@ public class TestImmWithRm32Handler : Group3BaseHandler
return false;
}
// Read the immediate value using BitConverter
uint imm32 = BitConverter.ToUInt32(CodeBuffer, position);
Decoder.SetPosition(position + 4);

View File

@ -23,18 +23,9 @@ public class TestImmWithRm8Handler : Group3BaseHandler
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
if (opcode != 0xF6)
return false;
// Check if the reg field of the ModR/M byte is 0 (TEST)
int position = Decoder.GetPosition();
if (position >= Length)
return false;
byte modRM = CodeBuffer[position];
byte reg = (byte)((modRM & 0x38) >> 3);
return reg == 0; // 0 = TEST
// This handler only handles opcode 0xF6
// The reg field check (for TEST operation) will be done in the Decode method
return opcode == 0xF6;
}
/// <summary>
@ -45,9 +36,6 @@ public class TestImmWithRm8Handler : Group3BaseHandler
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
// Set the mnemonic
instruction.Mnemonic = "test";
int position = Decoder.GetPosition();
if (position >= Length)
@ -57,20 +45,29 @@ public class TestImmWithRm8Handler : Group3BaseHandler
// Read the ModR/M byte
byte modRM = CodeBuffer[position++];
Decoder.SetPosition(position);
// Extract the fields from the ModR/M byte
byte mod = (byte)((modRM & 0xC0) >> 6);
byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for TEST
byte rm = (byte)(modRM & 0x07);
// Decode the destination operand
// Check if the reg field is 0 (TEST operation)
if (reg != 0)
{
return false; // Not a TEST instruction
}
// Set the mnemonic
instruction.Mnemonic = "test";
Decoder.SetPosition(position);
// Get the operand based on the addressing mode
string destOperand;
// Special case for direct register addressing (mod == 3)
// For direct register addressing (mod == 3), the r/m field specifies a register
if (mod == 3)
{
// Get the register name based on the rm field
destOperand = GetRegister8(rm);
}
else
@ -93,15 +90,4 @@ public class TestImmWithRm8Handler : Group3BaseHandler
return true;
}
/// <summary>
/// Gets the 8-bit register name for the given register index
/// </summary>
/// <param name="reg">The register index</param>
/// <returns>The register name</returns>
private static new string GetRegister8(byte reg)
{
string[] registerNames = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
return registerNames[reg & 0x07];
}
}