diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FinitHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FinitHandler.cs
index 8200819..9c10e8e 100644
--- a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FinitHandler.cs
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FinitHandler.cs
@@ -1,9 +1,7 @@
namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
-using X86Disassembler.X86.Operands;
-
///
-/// Handler for FINIT instruction (DB E3)
+/// Handler for FINIT instruction with WAIT prefix (0x9B 0xDB 0xE3) - Initialize FPU after checking for pending unmasked floating-point exceptions
///
public class FinitHandler : InstructionHandler
{
@@ -23,41 +21,51 @@ public class FinitHandler : InstructionHandler
/// True if this handler can decode the opcode
public override bool CanHandle(byte opcode)
{
- // FINIT is DB E3
- if (opcode != 0xDB) return false;
+ // FINIT with WAIT prefix starts with 0x9B
+ if (opcode != 0x9B) return false;
+ // Check if we can read the next two bytes
if (!Decoder.CanReadByte())
- {
return false;
- }
- // Check if the next byte is E3
- byte nextByte = Decoder.PeakByte();
- return nextByte == 0xE3;
+ // Check if the next bytes are 0xDB 0xE3 (for FINIT with WAIT)
+ var (nextByte, thirdByte) = Decoder.PeakTwoBytes();
+
+ // The sequence must be 9B DB E3 for FINIT with WAIT
+ return nextByte == 0xDB && thirdByte == 0xE3;
}
///
- /// Decodes a FINIT instruction
+ /// Decodes a FINIT instruction with WAIT prefix
///
/// The opcode of the instruction
/// The instruction object to populate
/// True if the instruction was successfully decoded
public override bool Decode(byte opcode, Instruction instruction)
{
+ // Skip the WAIT prefix (0x9B) - we already read it in CanHandle
if (!Decoder.CanReadByte())
- {
return false;
- }
- // Read the second byte of the opcode
+ // Read the second byte (0xDB)
byte secondByte = Decoder.ReadByte();
+ if (secondByte != 0xDB)
+ return false;
+
+ // Read the third byte (0xE3)
+ if (!Decoder.CanReadByte())
+ return false;
+
+ byte thirdByte = Decoder.ReadByte();
+ if (thirdByte != 0xE3)
+ return false;
// Set the instruction type
instruction.Type = InstructionType.Finit;
-
+
// FINIT has no operands
instruction.StructuredOperands = [];
-
+
return true;
}
}
diff --git a/X86Disassembler/X86/Handlers/FloatingPoint/Control/FninitHandler.cs b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FninitHandler.cs
new file mode 100644
index 0000000..1257ae8
--- /dev/null
+++ b/X86Disassembler/X86/Handlers/FloatingPoint/Control/FninitHandler.cs
@@ -0,0 +1,63 @@
+namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
+
+using X86Disassembler.X86.Operands;
+
+///
+/// Handler for FNINIT instruction (DB E3) - Initialize FPU without checking for pending unmasked exceptions
+///
+public class FninitHandler : InstructionHandler
+{
+ ///
+ /// Initializes a new instance of the FninitHandler class
+ ///
+ /// The instruction decoder that owns this handler
+ public FninitHandler(InstructionDecoder decoder)
+ : base(decoder)
+ {
+ }
+
+ ///
+ /// Checks if this handler can decode the given opcode
+ ///
+ /// The opcode to check
+ /// True if this handler can decode the opcode
+ public override bool CanHandle(byte opcode)
+ {
+ // FNINIT is DB E3
+ if (opcode != 0xDB) return false;
+
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Check if the next byte is E3
+ byte nextByte = Decoder.PeakByte();
+ return nextByte == 0xE3;
+ }
+
+ ///
+ /// Decodes a FNINIT instruction
+ ///
+ /// The opcode of the instruction
+ /// The instruction object to populate
+ /// True if the instruction was successfully decoded
+ public override bool Decode(byte opcode, Instruction instruction)
+ {
+ if (!Decoder.CanReadByte())
+ {
+ return false;
+ }
+
+ // Read the second byte of the opcode
+ byte secondByte = Decoder.ReadByte();
+
+ // Set the instruction type
+ instruction.Type = InstructionType.Fninit;
+
+ // FINIT has no operands
+ instruction.StructuredOperands = [];
+
+ return true;
+ }
+}
diff --git a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
index 37c6aed..91879eb 100644
--- a/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
+++ b/X86Disassembler/X86/Handlers/InstructionHandlerFactory.cs
@@ -437,7 +437,8 @@ public class InstructionHandlerFactory
// DB opcode handlers (control instructions)
_handlers.Add(new FloatingPoint.Control.FclexHandler(_decoder)); // FNCLEX (DB E2)
_handlers.Add(new FloatingPoint.Control.FclexWaitHandler(_decoder)); // FCLEX (9B DB E2)
- _handlers.Add(new FloatingPoint.Control.FinitHandler(_decoder)); // FINIT (DB E3)
+ _handlers.Add(new FloatingPoint.Control.FninitHandler(_decoder)); // FNINIT (DB E3)
+ _handlers.Add(new FloatingPoint.Control.FinitHandler(_decoder)); // FINIT (9B DB E3)
// DB opcode handlers (comparison instructions)
_handlers.Add(new FloatingPoint.Comparison.FucomiHandler(_decoder)); // FUCOMI (DB E8-EF)