mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-06-19 07:59:47 +03:00
Split FloatingPointHandler into specialized handlers for each instruction type and fixed FLDCW instruction formatting
This commit is contained in:
@ -70,7 +70,7 @@ public class Float32OperationHandler : FloatingPointBaseHandler
|
||||
if (mod != 3) // Memory operand
|
||||
{
|
||||
string operand = ModRMDecoder.DecodeModRM(mod, rm, false);
|
||||
instruction.Operands = $"dword ptr {operand}";
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else // Register operand (ST(i))
|
||||
{
|
||||
|
@ -69,8 +69,8 @@ public class Float64OperationHandler : FloatingPointBaseHandler
|
||||
// For memory operands, set the operand
|
||||
if (mod != 3) // Memory operand
|
||||
{
|
||||
string operand = ModRMDecoder.DecodeModRM(mod, rm, false);
|
||||
instruction.Operands = $"qword ptr {operand}";
|
||||
string operand = ModRMDecoder.DecodeModRM(mod, rm, true); // true for 64-bit operand
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else // Register operand (ST(i))
|
||||
{
|
||||
|
@ -69,8 +69,10 @@ public class Int16OperationHandler : FloatingPointBaseHandler
|
||||
// For memory operands, set the operand
|
||||
if (mod != 3) // Memory operand
|
||||
{
|
||||
// Need to modify the default dword ptr to word ptr for 16-bit integers
|
||||
string operand = ModRMDecoder.DecodeModRM(mod, rm, false);
|
||||
instruction.Operands = $"word ptr {operand}";
|
||||
operand = operand.Replace("dword ptr", "word ptr");
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else // Register operand (ST(i))
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ public class Int32OperationHandler : FloatingPointBaseHandler
|
||||
if (mod != 3) // Memory operand
|
||||
{
|
||||
string operand = ModRMDecoder.DecodeModRM(mod, rm, false);
|
||||
instruction.Operands = $"dword ptr {operand}";
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else // Register operand (ST(i))
|
||||
{
|
||||
|
@ -74,11 +74,20 @@ public class LoadStoreControlHandler : FloatingPointBaseHandler
|
||||
// Different operand types based on the instruction
|
||||
if (reg == 0 || reg == 2 || reg == 3) // fld, fst, fstp
|
||||
{
|
||||
instruction.Operands = $"dword ptr {operand}";
|
||||
// Keep the dword ptr prefix from ModRMDecoder
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else // fldenv, fldcw, fnstenv, fnstcw
|
||||
{
|
||||
instruction.Operands = operand;
|
||||
if (reg == 5) // fldcw - should use word ptr
|
||||
{
|
||||
instruction.Operands = operand.Replace("dword ptr", "word ptr");
|
||||
}
|
||||
else // fldenv, fnstenv, fnstcw
|
||||
{
|
||||
// Remove the dword ptr prefix for other control operations
|
||||
instruction.Operands = operand.Replace("dword ptr ", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Register operand (ST(i))
|
||||
|
@ -68,15 +68,16 @@ public class LoadStoreFloat64Handler : FloatingPointBaseHandler
|
||||
// For memory operands, set the operand
|
||||
if (mod != 3) // Memory operand
|
||||
{
|
||||
string operand = ModRMDecoder.DecodeModRM(mod, rm, false);
|
||||
string operand = ModRMDecoder.DecodeModRM(mod, rm, true); // true for 64-bit operand
|
||||
|
||||
if (reg == 0 || reg == 2 || reg == 3) // fld, fst, fstp
|
||||
{
|
||||
instruction.Operands = $"qword ptr {operand}";
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else // frstor, fnsave, fnstsw
|
||||
{
|
||||
instruction.Operands = operand;
|
||||
// Remove the qword ptr prefix for these operations
|
||||
instruction.Operands = operand.Replace("qword ptr ", "");
|
||||
}
|
||||
}
|
||||
else // Register operand (ST(i))
|
||||
|
@ -82,16 +82,22 @@ public class LoadStoreInt16Handler : FloatingPointBaseHandler
|
||||
{
|
||||
if (reg == 5 || reg == 7) // 64-bit integer
|
||||
{
|
||||
instruction.Operands = $"qword ptr {operand}";
|
||||
// Replace dword ptr with qword ptr for 64-bit integers
|
||||
operand = operand.Replace("dword ptr", "qword ptr");
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else // 16-bit integer
|
||||
{
|
||||
instruction.Operands = $"word ptr {operand}";
|
||||
// Replace dword ptr with word ptr for 16-bit integers
|
||||
operand = operand.Replace("dword ptr", "word ptr");
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
}
|
||||
else if (reg == 4 || reg == 6) // fbld, fbstp
|
||||
{
|
||||
instruction.Operands = $"tbyte ptr {operand}";
|
||||
// Replace dword ptr with tbyte ptr for 80-bit packed BCD
|
||||
operand = operand.Replace("dword ptr", "tbyte ptr");
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -73,11 +73,14 @@ public class LoadStoreInt32Handler : FloatingPointBaseHandler
|
||||
|
||||
if (reg == 0 || reg == 2 || reg == 3) // fild, fist, fistp
|
||||
{
|
||||
instruction.Operands = $"dword ptr {operand}";
|
||||
// Keep the dword ptr prefix for integer operations
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else if (reg == 5 || reg == 7) // fld, fstp (extended precision)
|
||||
{
|
||||
instruction.Operands = $"tword ptr {operand}";
|
||||
// Replace dword ptr with tword ptr for extended precision
|
||||
operand = operand.Replace("dword ptr", "tword ptr");
|
||||
instruction.Operands = operand;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using System;
|
||||
using Xunit;
|
||||
using X86Disassembler.X86;
|
||||
using X86Disassembler.X86.Handlers;
|
||||
using X86Disassembler.X86.Handlers.FloatingPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for floating-point instruction handlers
|
||||
@ -29,4 +30,224 @@ public class FloatingPointInstructionTests
|
||||
Assert.Equal("fnstsw", instruction.Mnemonic);
|
||||
Assert.Equal("ax", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the Float32OperationHandler for decoding FADD ST(0), ST(1) instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Float32OperationHandler_DecodesAddSt0St1_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FADD ST(0), ST(1) (D8 C1)
|
||||
byte[] codeBuffer = new byte[] { 0xD8, 0xC1 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fadd", instruction.Mnemonic);
|
||||
Assert.Equal("st(0), st(1)", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the Float32OperationHandler for decoding FADD dword ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Float32OperationHandler_DecodesAddMemory_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FADD dword ptr [eax] (D8 00)
|
||||
byte[] codeBuffer = new byte[] { 0xD8, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fadd", instruction.Mnemonic);
|
||||
Assert.Equal("dword ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the LoadStoreControlHandler for decoding FLD dword ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LoadStoreControlHandler_DecodesLoadMemory_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FLD dword ptr [eax] (D9 00)
|
||||
byte[] codeBuffer = new byte[] { 0xD9, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fld", instruction.Mnemonic);
|
||||
Assert.Equal("dword ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the LoadStoreControlHandler for decoding FLDCW [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LoadStoreControlHandler_DecodesLoadControlWord_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FLDCW [eax] (D9 28)
|
||||
byte[] codeBuffer = new byte[] { 0xD9, 0x28 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fldcw", instruction.Mnemonic);
|
||||
Assert.Equal("word ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the Int32OperationHandler for decoding FIADD dword ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Int32OperationHandler_DecodesIntegerAdd_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FIADD dword ptr [eax] (DA 00)
|
||||
byte[] codeBuffer = new byte[] { 0xDA, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fiadd", instruction.Mnemonic);
|
||||
Assert.Equal("dword ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the LoadStoreInt32Handler for decoding FILD dword ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LoadStoreInt32Handler_DecodesIntegerLoad_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FILD dword ptr [eax] (DB 00)
|
||||
byte[] codeBuffer = new byte[] { 0xDB, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fild", instruction.Mnemonic);
|
||||
Assert.Equal("dword ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the Float64OperationHandler for decoding FADD qword ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Float64OperationHandler_DecodesDoubleAdd_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FADD qword ptr [eax] (DC 00)
|
||||
byte[] codeBuffer = new byte[] { 0xDC, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fadd", instruction.Mnemonic);
|
||||
Assert.Equal("qword ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the Float64OperationHandler for decoding FADD ST(1), ST(0) instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Float64OperationHandler_DecodesAddSt1St0_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FADD ST(1), ST(0) (DC C1)
|
||||
byte[] codeBuffer = new byte[] { 0xDC, 0xC1 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fadd", instruction.Mnemonic);
|
||||
Assert.Equal("st(1), st(0)", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the LoadStoreFloat64Handler for decoding FLD qword ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LoadStoreFloat64Handler_DecodesDoubleLoad_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FLD qword ptr [eax] (DD 00)
|
||||
byte[] codeBuffer = new byte[] { 0xDD, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fld", instruction.Mnemonic);
|
||||
Assert.Equal("qword ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the Int16OperationHandler for decoding FIADD word ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Int16OperationHandler_DecodesShortAdd_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FIADD word ptr [eax] (DE 00)
|
||||
byte[] codeBuffer = new byte[] { 0xDE, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fiadd", instruction.Mnemonic);
|
||||
Assert.Equal("word ptr [eax]", instruction.Operands);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the LoadStoreInt16Handler for decoding FILD word ptr [eax] instruction
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void LoadStoreInt16Handler_DecodesShortLoad_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
// FILD word ptr [eax] (DF 00)
|
||||
byte[] codeBuffer = new byte[] { 0xDF, 0x00 };
|
||||
var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
|
||||
|
||||
// Act
|
||||
var instruction = decoder.DecodeInstruction();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(instruction);
|
||||
Assert.Equal("fild", instruction.Mnemonic);
|
||||
Assert.Equal("word ptr [eax]", instruction.Operands);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user