0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-05-19 20:01:17 +03:00

Added OrRm8R8Handler for decoding OR r/m8, r8 instruction (opcode 0x08)

This commit is contained in:
bird_egop 2025-04-13 02:35:48 +03:00
parent d46d03ce65
commit 618ee641a8
3 changed files with 158 additions and 0 deletions

View File

@ -193,6 +193,7 @@ public class InstructionHandlerFactory
_handlers.Add(new OrImmToRm32SignExtendedHandler(_codeBuffer, _decoder, _length)); _handlers.Add(new OrImmToRm32SignExtendedHandler(_codeBuffer, _decoder, _length));
_handlers.Add(new OrR8Rm8Handler(_codeBuffer, _decoder, _length)); _handlers.Add(new OrR8Rm8Handler(_codeBuffer, _decoder, _length));
_handlers.Add(new OrRm8R8Handler(_codeBuffer, _decoder, _length));
_handlers.Add(new OrR32Rm32Handler(_codeBuffer, _decoder, _length)); _handlers.Add(new OrR32Rm32Handler(_codeBuffer, _decoder, _length));
_handlers.Add(new OrAlImmHandler(_codeBuffer, _decoder, _length)); _handlers.Add(new OrAlImmHandler(_codeBuffer, _decoder, _length));
_handlers.Add(new OrEaxImmHandler(_codeBuffer, _decoder, _length)); _handlers.Add(new OrEaxImmHandler(_codeBuffer, _decoder, _length));

View File

@ -0,0 +1,85 @@
namespace X86Disassembler.X86.Handlers.Or;
/// <summary>
/// Handler for OR r/m8, r8 instruction (0x08)
/// </summary>
public class OrRm8R8Handler : InstructionHandler
{
// 8-bit register names
private static readonly string[] RegisterNames8 = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
/// <summary>
/// Initializes a new instance of the OrRm8R8Handler class
/// </summary>
/// <param name="codeBuffer">The buffer containing the code to decode</param>
/// <param name="decoder">The instruction decoder that owns this handler</param>
/// <param name="length">The length of the buffer</param>
public OrRm8R8Handler(byte[] codeBuffer, InstructionDecoder decoder, int length)
: base(codeBuffer, decoder, length)
{
}
/// <summary>
/// Checks if this handler can decode the given opcode
/// </summary>
/// <param name="opcode">The opcode to check</param>
/// <returns>True if this handler can decode the opcode</returns>
public override bool CanHandle(byte opcode)
{
return opcode == 0x08;
}
/// <summary>
/// Decodes an OR r/m8, r8 instruction
/// </summary>
/// <param name="opcode">The opcode of the instruction</param>
/// <param name="instruction">The instruction object to populate</param>
/// <returns>True if the instruction was successfully decoded</returns>
public override bool Decode(byte opcode, Instruction instruction)
{
// Set the mnemonic
instruction.Mnemonic = "or";
// Read the ModR/M byte
int position = Decoder.GetPosition();
if (position >= Length)
{
instruction.Operands = "??";
return true;
}
byte modRM = CodeBuffer[position++];
Decoder.SetPosition(position);
// Extract fields from ModR/M byte
byte mod = (byte)((modRM & 0xC0) >> 6); // Top 2 bits
byte reg = (byte)((modRM & 0x38) >> 3); // Middle 3 bits
byte rm = (byte)(modRM & 0x07); // Bottom 3 bits
// The register operand is in the reg field (8-bit register)
string regOperand = RegisterNames8[reg];
// Handle the r/m operand based on mod field
string rmOperand;
if (mod == 3) // Register-to-register
{
// Direct register addressing
rmOperand = RegisterNames8[rm];
}
else // Memory addressing
{
// Use ModRMDecoder for memory addressing, but we need to adjust for 8-bit operands
var modRMDecoder = new ModRMDecoder(CodeBuffer, Decoder, Length);
string memOperand = modRMDecoder.DecodeModRM(mod, rm, false); // false = not 64-bit
// Replace "dword ptr" with "byte ptr" for 8-bit operands
rmOperand = memOperand.Replace("dword ptr", "byte ptr");
}
// Set the operands (r/m8, r8 format)
instruction.Operands = $"{rmOperand}, {regOperand}";
return true;
}
}

View File

@ -0,0 +1,72 @@
namespace X86DisassemblerTests;
using System;
using Xunit;
using X86Disassembler.X86;
using X86Disassembler.X86.Handlers.Or;
/// <summary>
/// Tests for OR r/m8, r8 instruction handler
/// </summary>
public class OrRm8R8HandlerTests
{
/// <summary>
/// Tests the OrRm8R8Handler for decoding OR [mem], reg8 instruction
/// </summary>
[Fact]
public void OrRm8R8Handler_DecodesOrMemReg8_Correctly()
{
// Arrange
// OR [ebx+ecx*4+0x41], al (08 44 8B 41)
byte[] codeBuffer = new byte[] { 0x08, 0x44, 0x8B, 0x41 };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("or", instruction.Mnemonic);
Assert.Equal("byte ptr [ebx+ecx*4+0x41], al", instruction.Operands);
}
/// <summary>
/// Tests the OrRm8R8Handler for decoding OR reg8, reg8 instruction
/// </summary>
[Fact]
public void OrRm8R8Handler_DecodesOrRegReg8_Correctly()
{
// Arrange
// OR bl, ch (08 EB)
byte[] codeBuffer = new byte[] { 0x08, 0xEB };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("or", instruction.Mnemonic);
Assert.Equal("bl, ch", instruction.Operands);
}
/// <summary>
/// Tests the OrRm8R8Handler for handling insufficient bytes
/// </summary>
[Fact]
public void OrRm8R8Handler_HandlesInsufficientBytes_Gracefully()
{
// Arrange
// OR ?? (08) - missing ModR/M byte
byte[] codeBuffer = new byte[] { 0x08 };
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
// Act
var instruction = decoder.DecodeInstruction();
// Assert
Assert.NotNull(instruction);
Assert.Equal("or", instruction.Mnemonic);
Assert.Equal("??", instruction.Operands);
}
}