namespace X86Disassembler.X86.Handlers.Mov; /// /// Handler for MOV r32, r/m32 instruction (0x8B) and MOV r8, r/m8 instruction (0x8A) /// public class MovRegMemHandler : InstructionHandler { /// /// Initializes a new instance of the MovRegMemHandler class /// /// The buffer containing the code to decode /// The instruction decoder that owns this handler /// The length of the buffer public MovRegMemHandler(byte[] codeBuffer, InstructionDecoder decoder, int length) : base(codeBuffer, decoder, length) { } /// /// 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) { return opcode == 0x8A || opcode == 0x8B; } /// /// Decodes a MOV r32, r/m32 or MOV r8, r/m8 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) { // Set the mnemonic instruction.Mnemonic = "mov"; int position = Decoder.GetPosition(); if (position >= Length) { return false; } // Determine operand size (0 = 8-bit, 1 = 32-bit) bool operandSize32 = (opcode & 0x01) != 0; int operandSize = operandSize32 ? 32 : 8; // Read the ModR/M byte var (mod, reg, rm, memOperand) = ModRMDecoder.ReadModRM(); // Get register name based on size string regName = ModRMDecoder.GetRegisterName(reg, operandSize); // For mod == 3, both operands are registers if (mod == 3) { string rmRegName = ModRMDecoder.GetRegisterName(rm, operandSize); instruction.Operands = $"{rmRegName}, {regName}"; } else // Memory operand { instruction.Operands = $"{memOperand}, {regName}"; } return true; } }