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)