mirror of
				https://github.com/sampletext32/ParkanPlayground.git
				synced 2025-11-04 07:19:45 +03:00 
			
		
		
		
	Split FINIT/FNINIT handlers for proper instruction recognition
This commit is contained in:
		@@ -1,9 +1,7 @@
 | 
			
		||||
namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
 | 
			
		||||
 | 
			
		||||
using X86Disassembler.X86.Operands;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// 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
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class FinitHandler : InstructionHandler
 | 
			
		||||
{
 | 
			
		||||
@@ -23,41 +21,51 @@ public class FinitHandler : InstructionHandler
 | 
			
		||||
    /// <returns>True if this handler can decode the opcode</returns>
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Decodes a FINIT instruction
 | 
			
		||||
    /// Decodes a FINIT instruction with WAIT prefix
 | 
			
		||||
    /// </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)
 | 
			
		||||
    {
 | 
			
		||||
        // 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,63 @@
 | 
			
		||||
namespace X86Disassembler.X86.Handlers.FloatingPoint.Control;
 | 
			
		||||
 | 
			
		||||
using X86Disassembler.X86.Operands;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// Handler for FNINIT instruction (DB E3) - Initialize FPU without checking for pending unmasked exceptions
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class FninitHandler : InstructionHandler
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Initializes a new instance of the FninitHandler class
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="decoder">The instruction decoder that owns this handler</param>
 | 
			
		||||
    public FninitHandler(InstructionDecoder decoder)
 | 
			
		||||
        : base(decoder)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <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)
 | 
			
		||||
    {
 | 
			
		||||
        // 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;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Decodes a FNINIT 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)
 | 
			
		||||
    {
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user