From 6ed6a7bd00d48d1f8709a7901d57ecdeaf26f831 Mon Sep 17 00:00:00 2001 From: bird_egop Date: Sat, 12 Apr 2025 21:27:17 +0300 Subject: [PATCH] Fixed floating point instruction handling. Removed redundant FNSTSW AX check from FloatingPointHandler and added dedicated test for FnstswHandler. --- .../X86/Handlers/FloatingPointHandler.cs | 14 +++----- .../X86/Handlers/InstructionHandlerFactory.cs | 2 ++ .../Handlers/{ => Test}/TestAlImmHandler.cs | 2 +- .../Handlers/{ => Test}/TestEaxImmHandler.cs | 2 +- .../Handlers/{ => Test}/TestRegMem8Handler.cs | 2 +- .../Handlers/{ => Test}/TestRegMemHandler.cs | 2 +- .../FloatingPointInstructionTests.cs | 32 +++++++++++++++++++ 7 files changed, 42 insertions(+), 14 deletions(-) rename X86Disassembler/X86/Handlers/{ => Test}/TestAlImmHandler.cs (97%) rename X86Disassembler/X86/Handlers/{ => Test}/TestEaxImmHandler.cs (97%) rename X86Disassembler/X86/Handlers/{ => Test}/TestRegMem8Handler.cs (98%) rename X86Disassembler/X86/Handlers/{ => Test}/TestRegMemHandler.cs (98%) create mode 100644 X86DisassemblerTests/FloatingPointInstructionTests.cs diff --git a/X86Disassembler/X86/Handlers/FloatingPointHandler.cs b/X86Disassembler/X86/Handlers/FloatingPointHandler.cs index b24f36c..1a09972 100644 --- a/X86Disassembler/X86/Handlers/FloatingPointHandler.cs +++ b/X86Disassembler/X86/Handlers/FloatingPointHandler.cs @@ -114,8 +114,8 @@ public class FloatingPointHandler : InstructionHandler /// private static void InitializeTwoByteInstructions() { - // DF E0 - FNSTSW AX (Store FPU status word to AX without checking for pending unmasked floating-point exceptions) - TwoByteInstructions.Add(0xDFE0, "fnstsw"); + // We no longer need to handle FNSTSW AX (DF E0) here since we have a dedicated FnstswHandler + // that is registered before this handler in the InstructionHandlerFactory // Add other two-byte instructions as needed } @@ -166,14 +166,8 @@ public class FloatingPointHandler : InstructionHandler if (TwoByteInstructions.TryGetValue(twoByteOpcode, out string? mnemonic) && mnemonic != null) { instruction.Mnemonic = mnemonic; - - // Special handling for specific instructions - if (twoByteOpcode == 0xDFE0) // FNSTSW AX - { - instruction.Operands = "ax"; - Decoder.SetPosition(position + 1); // Skip the second byte - return true; - } + Decoder.SetPosition(position + 1); // Skip the second byte + return true; } } diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs index 43f3dcb..d6bb686 100644 --- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs +++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs @@ -1,3 +1,5 @@ +using X86Disassembler.X86.Handlers.Test; + namespace X86Disassembler.X86.Handlers; using X86Disassembler.X86.Handlers.Group1; diff --git a/X86Disassembler/X86/Handlers/TestAlImmHandler.cs b/X86Disassembler/X86/Handlers/Test/TestAlImmHandler.cs similarity index 97% rename from X86Disassembler/X86/Handlers/TestAlImmHandler.cs rename to X86Disassembler/X86/Handlers/Test/TestAlImmHandler.cs index 2ea44cd..bf53934 100644 --- a/X86Disassembler/X86/Handlers/TestAlImmHandler.cs +++ b/X86Disassembler/X86/Handlers/Test/TestAlImmHandler.cs @@ -1,4 +1,4 @@ -namespace X86Disassembler.X86.Handlers; +namespace X86Disassembler.X86.Handlers.Test; /// /// Handler for TEST AL, imm8 instruction (0xA8) diff --git a/X86Disassembler/X86/Handlers/TestEaxImmHandler.cs b/X86Disassembler/X86/Handlers/Test/TestEaxImmHandler.cs similarity index 97% rename from X86Disassembler/X86/Handlers/TestEaxImmHandler.cs rename to X86Disassembler/X86/Handlers/Test/TestEaxImmHandler.cs index 2c5efb4..0b480db 100644 --- a/X86Disassembler/X86/Handlers/TestEaxImmHandler.cs +++ b/X86Disassembler/X86/Handlers/Test/TestEaxImmHandler.cs @@ -1,4 +1,4 @@ -namespace X86Disassembler.X86.Handlers; +namespace X86Disassembler.X86.Handlers.Test; /// /// Handler for TEST EAX, imm32 instruction (0xA9) diff --git a/X86Disassembler/X86/Handlers/TestRegMem8Handler.cs b/X86Disassembler/X86/Handlers/Test/TestRegMem8Handler.cs similarity index 98% rename from X86Disassembler/X86/Handlers/TestRegMem8Handler.cs rename to X86Disassembler/X86/Handlers/Test/TestRegMem8Handler.cs index 37cefe9..c7f28bc 100644 --- a/X86Disassembler/X86/Handlers/TestRegMem8Handler.cs +++ b/X86Disassembler/X86/Handlers/Test/TestRegMem8Handler.cs @@ -1,4 +1,4 @@ -namespace X86Disassembler.X86.Handlers; +namespace X86Disassembler.X86.Handlers.Test; /// /// Handler for TEST r/m8, r8 instruction (0x84) diff --git a/X86Disassembler/X86/Handlers/TestRegMemHandler.cs b/X86Disassembler/X86/Handlers/Test/TestRegMemHandler.cs similarity index 98% rename from X86Disassembler/X86/Handlers/TestRegMemHandler.cs rename to X86Disassembler/X86/Handlers/Test/TestRegMemHandler.cs index b2bb77a..1ab8e90 100644 --- a/X86Disassembler/X86/Handlers/TestRegMemHandler.cs +++ b/X86Disassembler/X86/Handlers/Test/TestRegMemHandler.cs @@ -1,4 +1,4 @@ -namespace X86Disassembler.X86.Handlers; +namespace X86Disassembler.X86.Handlers.Test; /// /// Handler for TEST r/m32, r32 instruction (0x85) diff --git a/X86DisassemblerTests/FloatingPointInstructionTests.cs b/X86DisassemblerTests/FloatingPointInstructionTests.cs new file mode 100644 index 0000000..0c3b2b8 --- /dev/null +++ b/X86DisassemblerTests/FloatingPointInstructionTests.cs @@ -0,0 +1,32 @@ +namespace X86DisassemblerTests; + +using System; +using Xunit; +using X86Disassembler.X86; +using X86Disassembler.X86.Handlers; + +/// +/// Tests for floating-point instruction handlers +/// +public class FloatingPointInstructionTests +{ + /// + /// Tests the FnstswHandler for decoding FNSTSW AX instruction + /// + [Fact] + public void FnstswHandler_DecodesFnstswAx_Correctly() + { + // Arrange + // FNSTSW AX (DF E0) + byte[] codeBuffer = new byte[] { 0xDF, 0xE0 }; + var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length); + + // Act + var instruction = decoder.DecodeInstruction(); + + // Assert + Assert.NotNull(instruction); + Assert.Equal("fnstsw", instruction.Mnemonic); + Assert.Equal("ax", instruction.Operands); + } +}