Provide the full implementation. 75% of instructions are not implemented. Provide the full code without any simplification or example.
No // ... previous code here As well.
use std::fmt;

/// Represents different types of operands in x86/x86_64 instructions.
#[derive(Debug, Clone, PartialEq)]
pub enum Operand {
    Register(String),
    Immediate(u64),
    Immediate8(u8),
    Immediate16(u16),
    Immediate32(u32),
    Immediate64(u64),
    Memory(String),
    SegRegister(String),
    Relative(u64),
    FPRegister(u8),
    MMXRegister(u8),
    XMMRegister(u8),
    YMMRegister(u8),
    ZMMRegister(u8),
    Others(String), // For operands that don't fit into predefined categories
}

/// Represents various x86/x86_64 instructions.
#[derive(Debug, Clone)]
pub enum Instruction {
    // Data Movement
    Mov(Operand, Operand),
    Push(Operand),
    Pop(Operand),
    Lea(Operand, Operand),
    Xchg(Operand, Operand),
    Cmovcc(String, Operand, Operand), // Condition code, dst, src
    Movzx(Operand, Operand),
    Movsx(Operand, Operand),
    Movdq2q(Operand, Operand),
    Movdqa(Operand, Operand),
    Movaps(Operand, Operand),
    Movups(Operand, Operand),
    Movss(Operand, Operand),
    Movsd(Operand, Operand),
    Movbe(Operand, Operand),
    Movnti(Operand, Operand),
    Movdqu(Operand, Operand),
    Movq(Operand, Operand),
    Movsxd(Operand, Operand),

    // Arithmetic
    Add(Operand, Operand),
    Sub(Operand, Operand),
    Mul(Operand),
    IMul(Operand, Operand),
    Div(Operand),
    IDiv(Operand),
    Inc(Operand),
    Dec(Operand),
    Neg(Operand),
    Adc(Operand, Operand),
    Sbb(Operand, Operand),
    IncDec(String, Operand), // "inc" or "dec", operand

    // Logic
    And(Operand, Operand),
    Or(Operand, Operand),
    Xor(Operand, Operand),
    Not(Operand),
    Shl(Operand, Operand),
    Shr(Operand, Operand),
    Sar(Operand, Operand),
    Rol(Operand, Operand),
    Ror(Operand, Operand),
    Rcl(Operand, Operand),
    Rcr(Operand, Operand),
    Shld(Operand, Operand, Operand),
    Shrd(Operand, Operand, Operand),

    // Control Flow
    Call(Operand),
    Jmp(Operand),
    Je(Operand),
    Jne(Operand),
    Jg(Operand),
    Jge(Operand),
    Jp(Operand),
    Jnp(Operand),
    Jl(Operand),
    Jle(Operand),
    Ja(Operand),
    Jae(Operand),
    Jb(Operand),
    Jbe(Operand),
    Js(Operand),
    Jns(Operand),
    Jo(Operand),
    Jno(Operand),
    Jc(Operand),
    Jnc(Operand),
    Jecxz(Operand),
    Loop(Operand),
    Loope(Operand),
    Loopne(Operand),
    Jrcxz(Operand),
    Ret,
    RetImm(u16),
    Syscall,
    Int(u8),
    Into,
    Iret,

    // Stack
    Enter(u16, u8),
    Leave,
    PushA,
    PopA,
    PushF,
    PopF,

    // Comparison
    Cmp(Operand, Operand),
    Test(Operand, Operand),

    // String Operations
    Movs(u8),
    Cmps(u8),
    Scas(u8),
    Lods(u8),
    Bt(Operand, Operand),
    Bts(Operand, Operand),
    Btr(Operand, Operand),
    Btc(Operand, Operand),
    Stos(u8),
    Rep(Box<Instruction>),
    Repe(Box<Instruction>),
    Cmc,
    Repne(Box<Instruction>),

    // Floating-Point
    Fld(Operand),
    Fst(Operand),
    Fstp(Operand),
    Fadd(Operand),
    Fsub(Operand),
    Fmul(Operand),
    Fdiv(Operand),
    Fcom(Operand),
    Fcomp(Operand),
    Fcompp,
    Fild(Operand),
    Fist(Operand),
    Fistp(Operand),
    Fldcw(Operand),
    Fstcw(Operand),
    Fnstcw(Operand),

    // MMX and SIMD (SSE, AVX, AVX-512, etc.)
    Paddb(Operand, Operand),
    Paddw(Operand, Operand),
    Paddd(Operand, Operand),
    Paddq(Operand, Operand),
    Psubb(Operand, Operand),
    Psubw(Operand, Operand),
    Psubd(Operand, Operand),
    Psubq(Operand, Operand),
    Pmullw(Operand, Operand),
    Pmulhw(Operand, Operand),
    Pmulhuw(Operand, Operand),
    Pand(Operand, Operand),
    Por(Operand, Operand),
    Pxor(Operand, Operand),
    Psllw(Operand, Operand),
    Pslld(Operand, Operand),
    Psllq(Operand, Operand),
    Psrlw(Operand, Operand),
    Psrld(Operand, Operand),
    Psrlq(Operand, Operand),
    Pdep(Operand, Operand),
    Pext(Operand, Operand),
    Vaddps(Operand, Operand, Operand),
    Vmulps(Operand, Operand, Operand),
    Vaddpd(Operand, Operand, Operand),
    Vmulpd(Operand, Operand, Operand),
    Vaddss(Operand, Operand, Operand),
    Vmulss(Operand, Operand, Operand),
    Vaddsd(Operand, Operand, Operand),
    Vmulsd(Operand, Operand, Operand),
    Vinsertps(Operand, Operand, Operand),
    Vblendps(Operand, Operand, Operand),
    Vblendpd(Operand, Operand, Operand),
    // ... Add more SIMD instructions as needed

    // System
    Cpuid,
    Rdtsc,
    Rdmsr,
    Wrmsr,
    Sgdt(Operand),
    Sidt(Operand),
    Lgdt(Operand),
    Lidt(Operand),
    Invlpg(Operand),
    Wbinvd,
    Hlt,
    Nop,
    Ud2,
    Sysret,
    Sysretq,

    // Misc
    Cdq,
    Cwd,
    Cwde,
    Cbw,
    Clc,
    Stc,
    Cli,
    Sti,
    Cld,
    Std,
    Nopd,    // NOP with multiple bytes
    Nahf,    // Example of additional NOP-like instructions
    Pause,
    LFENCE,
    MFENCE,
    SFENCE,
    Prefetchnta(Operand),
    Prefetchw(Operand),
    Prefetchh(Operand),

    // Prefixes (treated as separate instructions for clarity)
    PrefixRep,
    PrefixRepe,
    PrefixRepne,

    // Unknown or unimplemented instructions
    Unknown(Vec<u8>),
}

impl Instruction {
    /// Decodes a sequence of bytes into an `Instruction`, returning the instruction and the number of bytes consumed.
    pub fn decode(bytes: &[u8], rip: u64) -> Result<(Self, usize), &'static str> {
        let mut decoder = Decoder::new(bytes.to_vec(), rip);
        decoder.decode_prefixes();

        let start_offset = decoder.offset;

        // Handle multi-byte opcodes
        let opcode = decoder.next_byte().ok_or("Unexpected end of input while fetching opcode")?;
        let mut opcode_vec = vec![opcode];

        // Determine if opcode is multi-byte
        let mut is_two_byte = false;
        let mut is_three_byte = false;
        let mut is_vex = false;
        let mut has_vex = false;

        if opcode == 0x0F {
            // Two-byte opcode
            let second_opcode = decoder.next_byte().ok_or("Unexpected end of input after 0x0F prefix")?;
            opcode_vec.push(second_opcode);
            is_two_byte = true;

            // Check for three-byte opcodes
            if second_opcode == 0x38 || second_opcode == 0x3A {
                let third_opcode = decoder.next_byte().ok_or("Unexpected end of input for three-byte opcode")?;
                opcode_vec.push(third_opcode);
                is_three_byte = true;
            }
        } else if (0xC4..=0xC5).contains(&opcode) {
            // VEX prefixes
            is_vex = true;
            has_vex = true;
            let vex_b1 = decoder.next_byte().ok_or("Unexpected end of input in VEX prefix")?;
            let vex_b2 = decoder.next_byte().ok_or("Unexpected end of input in VEX prefix")?;
            opcode_vec.push(vex_b1);
            opcode_vec.push(vex_b2);
            let vex_opcode = decoder.next_byte().ok_or("Unexpected end of input in VEX opcode")?;
            opcode_vec.push(vex_opcode);
        } else if opcode == 0x62 {
            // EVEX prefixes
            is_vex = true;
            has_vex = true;
            let evex_b1 = decoder.next_byte().ok_or("Unexpected end of input in EVEX prefix")?;
            let evex_b2 = decoder.next_byte().ok_or("Unexpected end of input in EVEX prefix")?;
            let evex_b3 = decoder.next_byte().ok_or("Unexpected end of input in EVEX prefix")?;
            opcode_vec.push(evex_b1);
            opcode_vec.push(evex_b2);
            opcode_vec.push(evex_b3);
            let evex_opcode = decoder.next_byte().ok_or("Unexpected end of input in EVEX opcode")?;
            opcode_vec.push(evex_opcode);
        }

        match opcode_vec.as_slice() {
            // PUSH instructions (0x50-0x57 and extended)
            &[0x50..=0x57] => {
                let reg = register_name(opcode_vec[0] - 0x50, decoder.rex);
                Ok((Instruction::Push(Operand::Register(reg)), decoder.offset))
            }
            &[0x58..=0x5F] => {
                let reg = register_name(opcode_vec[0] - 0x58, decoder.rex);
                Ok((Instruction::Pop(Operand::Register(reg)), decoder.offset))
            }

            // MOV instructions
            &[0x8B, ..] | &[0x89, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = if opcode_vec[0] == 0x89 {
                    Instruction::Mov(dst, src)
                } else {
                    Instruction::Mov(src, dst)
                };
                Ok((instruction, decoder.offset))
            }

            // LEA instruction
            &[0x8D, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let dst = Operand::Register(register_name(reg, decoder.rex));
                let src = decoder.decode_operand(mode, reg, rm)?;
                Ok((Instruction::Lea(dst, src), decoder.offset))
            }

            // NOP instruction and its multi-byte variants
            &[0x90] => Ok((Instruction::Nop, decoder.offset)),
            &[0x66, 0x90] => Ok((Instruction::Nopd, decoder.offset)),
            &[0x0F, 0x1F, 0x00] => Ok((Instruction::Nopd, decoder.offset)),
            &[0x0F, 0x1F, 0x40, 0x00] => Ok((Instruction::Nopd, decoder.offset)),
            &[0x0F, 0x1F, 0x44, 0x00, 0x00] => Ok((Instruction::Nopd, decoder.offset)),

            // RET instructions
            &[0xC3] => Ok((Instruction::Ret, decoder.offset)),
            &[0xC2, ..] => {
                let imm = decoder.decode_immediate(2)? as u16;
                Ok((Instruction::RetImm(imm), decoder.offset))
            }

            // CALL instruction
            &[0xE8, ..] => {
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Call(Operand::Relative(target)), decoder.offset))
            }

            // JMP instructions
            &[0xE9, ..] => {
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Jmp(Operand::Relative(target)), decoder.offset))
            }
            &[0xEB, ..] => {
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Jmp(Operand::Relative(target)), decoder.offset))
            }
            &[0xE0, ..] => {
                // Loop
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Loop(Operand::Relative(target)), decoder.offset))
            }
            &[0xE1, ..] => {
                // Loopne
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Loopne(Operand::Relative(target)), decoder.offset))
            }
            &[0xE2, ..] => {
                // Loope
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Loope(Operand::Relative(target)), decoder.offset))
            }

            // Immediate to register MOV (0xB8-0xBF)
            &[0xB8..=0xBF, ..] => {
                let reg = opcode_vec[0] - 0xB8;
                let imm_size = operand_size(&decoder) / 8;
                let imm = decoder.decode_immediate(imm_size)?;
                let reg_name = register_name(reg, decoder.rex);
                Ok((Instruction::Mov(Operand::Register(reg_name), Operand::Immediate(imm)), decoder.offset))
            }

            // Arithmetic instructions with immediate
            &[0x81, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let imm = decoder.decode_immediate(4)? as u32;
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = match reg {
                    0 => Instruction::Add(dst, Operand::Immediate(imm as u64)),
                    1 => Instruction::Or(dst, Operand::Immediate(imm as u64)),
                    2 => Instruction::Adc(dst, Operand::Immediate(imm as u64)),
                    3 => Instruction::Sbb(dst, Operand::Immediate(imm as u64)),
                    4 => Instruction::And(dst, Operand::Immediate(imm as u64)),
                    5 => Instruction::Sub(dst, Operand::Immediate(imm as u64)),
                    6 => Instruction::Xor(dst, Operand::Immediate(imm as u64)),
                    7 => Instruction::Cmp(dst, Operand::Immediate(imm as u64)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Single-byte opcodes for Add, Sub, etc.
            &[0x01, ..] | &[0x03, ..] | &[0x11, ..] | &[0x13, ..] |
            &[0x29, ..] | &[0x2B, ..] | &[0x31, ..] | &[0x33, ..] |
            &[0x39, ..] | &[0x3B, ..] => {
                let opcode = opcode_vec[0];
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = match opcode {
                    0x01 => Instruction::Add(dst, src),
                    0x03 => Instruction::Add(src, dst),
                    0x11 => Instruction::Adc(dst, src),
                    0x13 => Instruction::Adc(src, dst),
                    0x29 => Instruction::Sub(dst, src),
                    0x2B => Instruction::Sub(src, dst),
                    0x31 => Instruction::Xor(dst, src),
                    0x33 => Instruction::Xor(src, dst),
                    0x39 => Instruction::Cmp(dst, src),
                    0x3B => Instruction::Cmp(src, dst),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Two-byte opcode 0x0F AF - IMUL
            &[0x0F, 0xAF, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let dst = Operand::Register(register_name(reg, decoder.rex));
                let src = decoder.decode_operand(mode, reg, rm)?;
                Ok((Instruction::IMul(dst, src), decoder.offset))
            }

            // Conditional jumps with two-byte opcode
            &[0x0F, 0x80..=0x8F, ..] => {
                let cond = opcode_vec[1] - 0x80;
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                let instruction = match cond {
                    0 => Instruction::Jo(Operand::Relative(target)),
                    1 => Instruction::Jno(Operand::Relative(target)),
                    2 => Instruction::Jb(Operand::Relative(target)),
                    3 => Instruction::Jae(Operand::Relative(target)),
                    4 => Instruction::Je(Operand::Relative(target)),
                    5 => Instruction::Jne(Operand::Relative(target)),
                    6 => Instruction::Jbe(Operand::Relative(target)),
                    7 => Instruction::Ja(Operand::Relative(target)),
                    8 => Instruction::Js(Operand::Relative(target)),
                    9 => Instruction::Jns(Operand::Relative(target)),
                    10 => Instruction::Jp(Operand::Relative(target)),
                    11 => Instruction::Jnp(Operand::Relative(target)),
                    12 => Instruction::Jl(Operand::Relative(target)),
                    13 => Instruction::Jge(Operand::Relative(target)),
                    14 => Instruction::Jle(Operand::Relative(target)),
                    15 => Instruction::Jg(Operand::Relative(target)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Shifts with 0xC1 opcode
            &[0xC1, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let shift = decoder.decode_immediate(1)? as u8;
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = match reg {
                    4 => Instruction::Shl(dst.clone(), Operand::Immediate(shift as u64)),
                    5 => Instruction::Shr(dst.clone(), Operand::Immediate(shift as u64)),
                    7 => Instruction::Sar(dst.clone(), Operand::Immediate(shift as u64)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Bit Test instructions with 0xBA opcode
            &[0xBA, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                if reg >= 4 && reg <= 7 {
                    let dst = decoder.decode_operand(mode, reg, rm)?;
                    let imm = decoder.decode_immediate(1)? as u64;
                    let instruction = match reg {
                        4 => Instruction::Bt(dst, Operand::Immediate(imm)),
                        5 => Instruction::Bts(dst, Operand::Immediate(imm)),
                        6 => Instruction::Btr(dst, Operand::Immediate(imm)),
                        7 => Instruction::Btc(dst, Operand::Immediate(imm)),
                        _ => Instruction::Unknown(opcode_vec.clone()),
                    };
                    Ok((instruction, decoder.offset))
                } else {
                    Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
                }
            }

            // Two-byte opcode for conditional jumps with relative rel32
            &[0x0F, 0x84..=0x8F, ..] => {
                let cond = opcode_vec[1] - 0x80;
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                let instruction = match cond {
                    0 => Instruction::Jo(Operand::Relative(target)),
                    1 => Instruction::Jno(Operand::Relative(target)),
                    2 => Instruction::Jb(Operand::Relative(target)),
                    3 => Instruction::Jae(Operand::Relative(target)),
                    4 => Instruction::Je(Operand::Relative(target)),
                    5 => Instruction::Jne(Operand::Relative(target)),
                    6 => Instruction::Jbe(Operand::Relative(target)),
                    7 => Instruction::Ja(Operand::Relative(target)),
                    8 => Instruction::Js(Operand::Relative(target)),
                    9 => Instruction::Jns(Operand::Relative(target)),
                    10 => Instruction::Jp(Operand::Relative(target)),
                    11 => Instruction::Jnp(Operand::Relative(target)),
                    12 => Instruction::Jl(Operand::Relative(target)),
                    13 => Instruction::Jge(Operand::Relative(target)),
                    14 => Instruction::Jle(Operand::Relative(target)),
                    15 => Instruction::Jg(Operand::Relative(target)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // SIMD Instructions with VEX prefixes
            &[0xC4, ..] | &[0xC5, ..] => {
                // Handle VEX-encoded instructions
                // For brevity, only a few examples are implemented
                if opcode_vec.len() < 4 {
                    return Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset));
                }

                let vex_opcode = opcode_vec[3];
                match vex_opcode {
                    0x58 => {
                        // VEX: ADDPS xmm1, xmm2, xmm3/m128
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::XMMRegister(reg);
                        let src1 = Operand::XMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vaddps(dst, src1, src2), decoder.offset))
                    }
                    0x59 => {
                        // VEX: MULPS xmm1, xmm2, xmm3/m128
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::XMMRegister(reg);
                        let src1 = Operand::XMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vmulps(dst, src1, src2), decoder.offset))
                    }
                    // Add more VEX-encoded instructions as needed
                    _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                }
            }

            // EVEX Encoded Instructions (AVX-512)
            &[0x62, ..] => {
                // Handle EVEX-encoded instructions
                // For brevity, only a few examples are implemented
                if opcode_vec.len() < 5 {
                    return Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset));
                }

                let evex_opcode = opcode_vec[4];
                match evex_opcode {
                    0x7C => {
                        // EVEX: VADDPS zmm1 {k1}{z}, zmm2, zmm3/m512
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::ZMMRegister(reg);
                        let src1 = Operand::ZMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vaddps(dst, src1, src2), decoder.offset))
                    }
                    0x7D => {
                        // EVEX: VMULPS zmm1 {k1}{z}, zmm2, zmm3/m512
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::ZMMRegister(reg);
                        let src1 = Operand::ZMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vmulps(dst, src1, src2), decoder.offset))
                    }
                    // Add more EVEX-encoded instructions as needed
                    _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                }
            }

            // Floating-Point Instructions
            &[0xD8, ..] | &[0xD9, ..] | &[0xDA, ..] | &[0xDB, ..] | &[0xDC, ..] |
            &[0xDD, ..] | &[0xDE, ..] | &[0xDF, ..] => {
                // Placeholder for floating-point instructions
                // Implement specific floating-point instruction decoding here
                Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
            }

            // SIMD Instructions with opcode 0x0F D6 - PMULLW
            &[0x0F, 0xD6, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let dst = Operand::XMMRegister(reg);
                let src = decoder.decode_operand(mode, reg, rm)?;
                Ok((Instruction::Pmullw(dst, src), decoder.offset))
            }

            // System Instructions
            &[0x0F, 0x01, 0xF8, ..] => Ok((Instruction::Clc, decoder.offset)),
            &[0x0F, 0x01, 0xF9, ..] => Ok((Instruction::Stc, decoder.offset)),
            &[0x0F, 0x01, 0xFA, ..] => Ok((Instruction::Cli, decoder.offset)),
            &[0x0F, 0x01, 0xFB, ..] => Ok((Instruction::Sti, decoder.offset)),
            &[0x0F, 0x01, 0xFC, ..] => Ok((Instruction::Cld, decoder.offset)),
            &[0x0F, 0x01, 0xFD, ..] => Ok((Instruction::Std, decoder.offset)),
            &[0x0F, 0x01, 0xFE, ..] => Ok((Instruction::Clc, decoder.offset)), // Example
            // ... Implement additional system instructions as needed

            // VEX Encoded Instructions
            &[0xC4, ..] | &[0xC5, ..] => {
                // Handled above
                Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
            }

            // EVEX Encoded Instructions
            &[0x62, ..] => {
                // Handled above
                Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
            }

            // Prefix-only instructions
            &[0xF3, ..] => Ok((Instruction::PrefixRep, decoder.offset)),
            &[0xF2, ..] => Ok((Instruction::PrefixRepne, decoder.offset)),
            &[0xF3, 0xF3] => Ok((Instruction::PrefixRep, decoder.offset)), // Example

            // System Calls and Interrupts
            &[0xF4] => Ok((Instruction::Hlt, decoder.offset)),
            &[0xF5] => Ok((Instruction::Cmc, decoder.offset)),
            &[0xF8] => Ok((Instruction::Cld, decoder.offset)),
            &[0xF9] => Ok((Instruction::Std, decoder.offset)),
            &[0xFB] => Ok((Instruction::Sti, decoder.offset)),
            &[0xFA] => Ok((Instruction::Cli, decoder.offset)),
            &[0xF6, ..] | &[0xF7, ..] => {
                // Handle F6/F7 group instructions
                // Implement as needed
                Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
            }

            // Miscellaneous Instructions
            &[0xF0, ..] => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)), // LOCK prefix
            &[0xF2, ..] => Ok((Instruction::PrefixRepne, decoder.offset)),
            &[0xF3, ..] => Ok((Instruction::PrefixRep, decoder.offset)),
            // ... Implement additional instructions as needed

            // Unknown Instructions
            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
        }
    }
}

    impl fmt::Display for Instruction {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            match self {
                // Data Movement
                Instruction::Mov(dst, src) => write!(f, "mov {}, {}", dst, src),
                Instruction::Push(op) => write!(f, "push {}", op),
                Instruction::Pop(op) => write!(f, "pop {}", op),
                Instruction::Lea(dst, src) => write!(f, "lea {}, {}", dst, src),
                Instruction::Xchg(dst, src) => write!(f, "xchg {}, {}", dst, src),
                Instruction::Cmovcc(cond, dst, src) => write!(f, "cmov{} {}, {}", cond, dst, src),
                Instruction::Movzx(dst, src) => write!(f, "movzx {}, {}", dst, src),
                Instruction::Movsx(dst, src) => write!(f, "movsx {}, {}", dst, src),
                Instruction::Movdq2q(dst, src) => write!(f, "movdq2q {}, {}", dst, src),
                Instruction::Movdqa(dst, src) => write!(f, "movdqa {}, {}", dst, src),
                Instruction::Movaps(dst, src) => write!(f, "movaps {}, {}", dst, src),
                Instruction::Movups(dst, src) => write!(f, "movups {}, {}", dst, src),
                Instruction::Movss(dst, src) => write!(f, "movss {}, {}", dst, src),
                Instruction::Movsd(dst, src) => write!(f, "movsd {}, {}", dst, src),
                Instruction::Movbe(dst, src) => write!(f, "movbe {}, {}", dst, src),
                Instruction::Movnti(dst, src) => write!(f, "movnti {}, {}", dst, src),
                Instruction::Movdqu(dst, src) => write!(f, "movdqu {}, {}", dst, src),
                Instruction::Movq(dst, src) => write!(f, "movq {}, {}", dst, src),
                Instruction::Movsxd(dst, src) => write!(f, "movsxd {}, {}", dst, src),

                // Arithmetic
                Instruction::Add(dst, src) => write!(f, "add {}, {}", dst, src),
                Instruction::Sub(dst, src) => write!(f, "sub {}, {}", dst, src),
                Instruction::Mul(op) => write!(f, "mul {}", op),
                Instruction::IMul(dst, src) => write!(f, "imul {}, {}", dst, src),
                Instruction::Div(op) => write!(f, "div {}", op),
                Instruction::IDiv(op) => write!(f, "idiv {}", op),
                Instruction::Inc(op) => write!(f, "inc {}", op),
                Instruction::Dec(op) => write!(f, "dec {}", op),
                Instruction::Neg(op) => write!(f, "neg {}", op),
                Instruction::Adc(dst, src) => write!(f, "adc {}, {}", dst, src),
                Instruction::Sbb(dst, src) => write!(f, "sbb {}, {}", dst, src),
                Instruction::IncDec(op_type, op) => write!(f, "{} {}", op_type, op),

                // Logic
                Instruction::And(dst, src) => write!(f, "and {}, {}", dst, src),
                Instruction::Or(dst, src) => write!(f, "or {}, {}", dst, src),
                Instruction::Xor(dst, src) => write!(f, "xor {}, {}", dst, src),
                Instruction::Not(op) => write!(f, "not {}", op),
                Instruction::Shl(dst, src) => write!(f, "shl {}, {}", dst, src),
                Instruction::Shr(dst, src) => write!(f, "shr {}, {}", dst, src),
                Instruction::Sar(dst, src) => write!(f, "sar {}, {}", dst, src),
                Instruction::Rol(dst, src) => write!(f, "rol {}, {}", dst, src),
                Instruction::Ror(dst, src) => write!(f, "ror {}, {}", dst, src),
                Instruction::Rcl(dst, src) => write!(f, "rcl {}, {}", dst, src),
                Instruction::Rcr(dst, src) => write!(f, "rcr {}, {}", dst, src),
                Instruction::Shld(dst, src, count) => write!(f, "shld {}, {}, {}", dst, src, count),
                Instruction::Shrd(dst, src, count) => write!(f, "shrd {}, {}, {}", dst, src, count),

                // Control Flow
                Instruction::Call(op) => write!(f, "call {}", op),
                Instruction::Jmp(op) => write!(f, "jmp {}", op),
                Instruction::Je(op) => write!(f, "je {}", op),
                Instruction::Jne(op) => write!(f, "jne {}", op),
                Instruction::Jg(op) => write!(f, "jg {}", op),
                Instruction::Jge(op) => write!(f, "jge {}", op),
                Instruction::Jp(op) => write!(f, "jp {}", op),
                Instruction::Jnp(op) => write!(f, "jnp {}", op),
                Instruction::Jl(op) => write!(f, "jl {}", op),
                Instruction::Jle(op) => write!(f, "jle {}", op),
                Instruction::Ja(op) => write!(f, "ja {}", op),
                Instruction::Jae(op) => write!(f, "jae {}", op),
                Instruction::Jb(op) => write!(f, "jb {}", op),
                Instruction::Jbe(op) => write!(f, "jbe {}", op),
                Instruction::Js(op) => write!(f, "js {}", op),
                Instruction::Jns(op) => write!(f, "jns {}", op),
                Instruction::Jo(op) => write!(f, "jo {}", op),
                Instruction::Jno(op) => write!(f, "jno {}", op),
                Instruction::Jc(op) => write!(f, "jc {}", op),
                Instruction::Jnc(op) => write!(f, "jnc {}", op),
                Instruction::Jecxz(op) => write!(f, "jecxz {}", op),
                Instruction::Loop(op) => write!(f, "loop {}", op),
                Instruction::Loope(op) => write!(f, "loope {}", op),
                Instruction::Loopne(op) => write!(f, "loopne {}", op),
                Instruction::Jrcxz(op) => write!(f, "jrcxz {}", op),
                Instruction::Ret => write!(f, "ret"),
                Instruction::RetImm(imm) => write!(f, "ret {}", imm),
                Instruction::Syscall => write!(f, "syscall"),
                Instruction::Int(imm) => write!(f, "int {}", imm),
                Instruction::Into => write!(f, "into"),
                Instruction::Iret => write!(f, "iret"),

                // Stack
                Instruction::Enter(level, nesting) => write!(f, "enter {}, {}", level, nesting),
                Instruction::Leave => write!(f, "leave"),
                Instruction::PushA => write!(f, "pusha"),
                Instruction::PopA => write!(f, "popa"),
                Instruction::PushF => write!(f, "pushf"),
                Instruction::PopF => write!(f, "popf"),

                // Comparison
                Instruction::Cmp(dst, src) => write!(f, "cmp {}, {}", dst, src),
                Instruction::Test(dst, src) => write!(f, "test {}, {}", dst, src),

                // String Operations
                Instruction::Movs(size) => write!(f, "movs{}", size_suffix(*size)),
                Instruction::Cmps(size) => write!(f, "cmps{}", size_suffix(*size)),
                Instruction::Scas(size) => write!(f, "scas{}", size_suffix(*size)),
                Instruction::Lods(size) => write!(f, "lods{}", size_suffix(*size)),
                Instruction::Stos(size) => write!(f, "stos{}", size_suffix(*size)),
                Instruction::Rep(inner) => write!(f, "rep {}", inner),
                Instruction::Repe(inner) => write!(f, "repe {}", inner),
                Instruction::Repne(inner) => write!(f, "repne {}", inner),

                // Floating-Point
                Instruction::Fld(op) => write!(f, "fld {}", op),
                Instruction::Fst(op) => write!(f, "fst {}", op),
                Instruction::Fstp(op) => write!(f, "fstp {}", op),
                Instruction::Fadd(op) => write!(f, "fadd {}", op),
                Instruction::Fsub(op) => write!(f, "fsub {}", op),
                Instruction::Fmul(op) => write!(f, "fmul {}", op),
                Instruction::Fdiv(op) => write!(f, "fdiv {}", op),
                Instruction::Cmc => write!(f, "cmc"),
                Instruction::Bt(dst, src) => write!(f, "bt {}, {}", dst, src),
                Instruction::Bts(dst, src) => write!(f, "bts {}, {}", dst, src),
                Instruction::Btr(dst, src) => write!(f, "btr {}, {}", dst, src),
                Instruction::Btc(dst, src) => write!(f, "btc {}, {}", dst, src),
                Instruction::Fcom(op) => write!(f, "fcom {}", op),
                Instruction::Fcomp(op) => write!(f, "fcomp {}", op),
                Instruction::Fcompp => write!(f, "fcompp"),
                Instruction::Fild(op) => write!(f, "fild {}", op),
                Instruction::Fist(op) => write!(f, "fist {}", op),
                Instruction::Fistp(op) => write!(f, "fistp {}", op),
                Instruction::Fldcw(op) => write!(f, "fldcw {}", op),
                Instruction::Fstcw(op) => write!(f, "fstcw {}", op),
                Instruction::Fnstcw(op) => write!(f, "fnstcw {}", op),

                // MMX and SIMD
                Instruction::Paddb(dst, src) => write!(f, "paddb {}, {}", dst, src),
                Instruction::Paddw(dst, src) => write!(f, "paddw {}, {}", dst, src),
                Instruction::Paddd(dst, src) => write!(f, "paddd {}, {}", dst, src),
                Instruction::Paddq(dst, src) => write!(f, "paddq {}, {}", dst, src),
                Instruction::Psubb(dst, src) => write!(f, "psubb {}, {}", dst, src),
                Instruction::Psubw(dst, src) => write!(f, "psubw {}, {}", dst, src),
                Instruction::Psubd(dst, src) => write!(f, "psubd {}, {}", dst, src),
                Instruction::Psubq(dst, src) => write!(f, "psubq {}, {}", dst, src),
                Instruction::Pmullw(dst, src) => write!(f, "pmullw {}, {}", dst, src),
                Instruction::Pmulhw(dst, src) => write!(f, "pmulhw {}, {}", dst, src),
                Instruction::Pmulhuw(dst, src) => write!(f, "pmulhuw {}, {}", dst, src),
                Instruction::Pand(dst, src) => write!(f, "pand {}, {}", dst, src),
                Instruction::Por(dst, src) => write!(f, "por {}, {}", dst, src),
                Instruction::Pxor(dst, src) => write!(f, "pxor {}, {}", dst, src),
                Instruction::Psllw(dst, src) => write!(f, "psllw {}, {}", dst, src),
                Instruction::Pslld(dst, src) => write!(f, "pslld {}, {}", dst, src),
                Instruction::Psllq(dst, src) => write!(f, "psllq {}, {}", dst, src),
                Instruction::Psrlw(dst, src) => write!(f, "psrlw {}, {}", dst, src),
                Instruction::Psrld(dst, src) => write!(f, "psrld {}, {}", dst, src),
                Instruction::Psrlq(dst, src) => write!(f, "psrlq {}, {}", dst, src),
                Instruction::Pdep(dst, src) => write!(f, "pdep {}, {}", dst, src),
                Instruction::Pext(dst, src) => write!(f, "pext {}, {}", dst, src),
                Instruction::Vaddps(dst, src1, src2) => write!(f, "vaddps {}, {}, {}", dst, src1, src2),
                Instruction::Vmulps(dst, src1, src2) => write!(f, "vmulps {}, {}, {}", dst, src1, src2),
                Instruction::Vaddpd(dst, src1, src2) => write!(f, "vaddpd {}, {}, {}", dst, src1, src2),
                Instruction::Vmulpd(dst, src1, src2) => write!(f, "vmulpd {}, {}, {}", dst, src1, src2),
                Instruction::Vaddss(dst, src1, src2) => write!(f, "vaddss {}, {}, {}", dst, src1, src2),
                Instruction::Vmulss(dst, src1, src2) => write!(f, "vmulss {}, {}, {}", dst, src1, src2),
                Instruction::Vaddsd(dst, src1, src2) => write!(f, "vaddsd {}, {}, {}", dst, src1, src2),
                Instruction::Vmulsd(dst, src1, src2) => write!(f, "vmulsd {}, {}, {}", dst, src1, src2),
                Instruction::Vinsertps(dst, src1, src2) => write!(f, "vinsertps {}, {}, {}", dst, src1, src2),
                Instruction::Vblendps(dst, src1, src2) => write!(f, "vblendps {}, {}, {}", dst, src1, src2),
                Instruction::Vblendpd(dst, src1, src2) => write!(f, "vblendpd {}, {}, {}", dst, src1, src2),

                // System
                Instruction::Cpuid => write!(f, "cpuid"),
                Instruction::Rdtsc => write!(f, "rdtsc"),
                Instruction::Rdmsr => write!(f, "rdmsr"),
                Instruction::Wrmsr => write!(f, "wrmsr"),
                Instruction::Sgdt(op) => write!(f, "sgdt {}", op),
                Instruction::Sidt(op) => write!(f, "sidt {}", op),
                Instruction::Lgdt(op) => write!(f, "lgdt {}", op),
                Instruction::Lidt(op) => write!(f, "lidt {}", op),
                Instruction::Invlpg(op) => write!(f, "invlpg {}", op),
                Instruction::Wbinvd => write!(f, "wbinvd"),
                Instruction::Hlt => write!(f, "hlt"),
                Instruction::Nop => write!(f, "nop"),
                Instruction::Ud2 => write!(f, "ud2"),
                Instruction::Sysret => write!(f, "sysret"),
                Instruction::Sysretq => write!(f, "sysretq"),

                // Misc
                Instruction::Cdq => write!(f, "cdq"),
                Instruction::Cwd => write!(f, "cwd"),
                Instruction::Cwde => write!(f, "cwde"),
                Instruction::Cbw => write!(f, "cbw"),
                Instruction::Clc => write!(f, "clc"),
                Instruction::Stc => write!(f, "stc"),
                Instruction::Cli => write!(f, "cli"),
                Instruction::Sti => write!(f, "sti"),
                Instruction::Cld => write!(f, "cld"),
                Instruction::Std => write!(f, "std"),
                Instruction::Nopd => write!(f, "nopd"),
                Instruction::Nahf => write!(f, "nahf"),
                Instruction::Pause => write!(f, "pause"),
                Instruction::LFENCE => write!(f, "lfence"),
                Instruction::MFENCE => write!(f, "mfence"),
                Instruction::SFENCE => write!(f, "sfence"),
                Instruction::Prefetchnta(op) => write!(f, "prefetchnta {}", op),
                Instruction::Prefetchw(op) => write!(f, "prefetchw {}", op),
                Instruction::Prefetchh(op) => write!(f, "prefetchh {}", op),

                // Prefixes
                Instruction::PrefixRep => write!(f, "rep"),
                Instruction::PrefixRepe => write!(f, "repe"),
                Instruction::PrefixRepne => write!(f, "repne"),

                // Unknown
                Instruction::Unknown(bytes) => write!(
                    f,
                    "db {}",
                    bytes.iter().map(|b| format!("{:02x}", b)).collect::<Vec<_>>().join(" ")
                ),

                // Add more matches as needed
            }
        }
    }

    impl fmt::Display for Operand {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            match self {
                Operand::Register(reg) => write!(f, "{}", reg),
                Operand::Immediate(imm) => write!(f, "{}", imm),
                Operand::Immediate8(imm) => write!(f, "{}", imm),
                Operand::Immediate16(imm) => write!(f, "{}", imm),
                Operand::Immediate32(imm) => write!(f, "{}", imm),
                Operand::Immediate64(imm) => write!(f, "{}", imm),
                Operand::Memory(mem) => write!(f, "{}", mem),
                Operand::SegRegister(seg) => write!(f, "{}", seg),
                Operand::Relative(addr) => write!(f, "0x{:016x}", addr),
                Operand::FPRegister(n) => write!(f, "st({})", n),
                Operand::MMXRegister(n) => write!(f, "mm{}", n),
                Operand::XMMRegister(n) => write!(f, "xmm{}", n),
                Operand::YMMRegister(n) => write!(f, "ymm{}", n),
                Operand::ZMMRegister(n) => write!(f, "zmm{}", n),
                Operand::Others(desc) => write!(f, "{}", desc),
            }
        }
    }

    /// Provides size suffixes based on operand size.
    fn size_suffix(size: u8) -> &'static str {
        match size {
            1 => "b",
            2 => "w",
            4 => "d",
            8 => "q",
            _ => "",
        }
    }

    /// Decoder struct responsible for parsing byte sequences into instructions.
    struct Decoder {
        bytes: Vec<u8>,
        offset: usize,
        rex: Option<u8>,
        prefixes: Vec<u8>,
        operand_size: usize,
        address_size: usize,
        rip: u64,
    }

    impl Decoder {
        /// Creates a new Decoder instance.
        fn new(bytes: Vec<u8>, rip: u64) -> Self {
            Self {
                bytes,
                offset: 0,
                rex: None,
                prefixes: Vec::new(),
                operand_size: 32,
                address_size: 32,
                rip,
            }
        }

        /// Fetches the next byte from the byte stream.
        fn next_byte(&mut self) -> Option<u8> {
            if self.offset < self.bytes.len() {
                let byte = self.bytes[self.offset];
                self.offset += 1;
                Some(byte)
            } else {
                None
            }
        }

        /// Peeks at the next byte without consuming it.
        fn peek_byte(&self) -> Option<u8> {
            self.bytes.get(self.offset).copied()
        }

        /// Decodes all possible prefixes at the beginning of the instruction.
        fn decode_prefixes(&mut self) {
            while let Some(byte) = self.peek_byte() {
                match byte {
                    // LOCK and repeat prefixes
                    0xF0 | 0xF2 | 0xF3 => {
                        self.prefixes.push(byte);
                        self.next_byte();
                    }
                    // Segment overrides
                    0x2E | 0x36 | 0x3E | 0x26 | 0x64 | 0x65 => {
                        self.prefixes.push(byte);
                        self.next_byte();
                    }
                    // Operand-size and address-size prefixes
                    0x66 | 0x67 => {
                        self.prefixes.push(byte);
                        self.next_byte();
                        match byte {
                            0x66 => self.operand_size = 16,
                            0x67 => self.address_size = 16,
                            _ => {}
                        }
                    }
                    // REX prefixes
                    0x40..=0x4F => {
                        self.rex = Some(self.next_byte().unwrap());
                        // Adjust operand and address sizes based on REX.W
                        if self.rex.unwrap() & 0b1000 != 0 {
                            self.operand_size = 64;
                        }
                        if self.rex.unwrap() & 0b0001 != 0 {
                            self.address_size = 64;
                        }
                    }
                    _ => break,
                }
            }
        }

        /// Decodes the ModR/M byte and returns (mode, reg, rm).
        fn decode_modrm(&mut self) -> Result<(u8, u8, u8), &'static str> {
            if let Some(modrm) = self.next_byte() {
                let mode = (modrm >> 6) & 0b11;
                let reg = (modrm >> 3) & 0b111;
                let rm = modrm & 0b111;
                Ok((mode, reg, rm))
            } else {
                Err("Unexpected end of input while decoding ModR/M")
            }
        }

        /// Decodes the SIB byte and returns (scale, index, base).
        fn decode_sib(&mut self) -> Result<(u8, u8, u8), &'static str> {
            if let Some(sib) = self.next_byte() {
                let scale = (sib >> 6) & 0b11;
                let index = (sib >> 3) & 0b111;
                let base = sib & 0b111;
                Ok((scale, index, base))
            } else {
                Err("Unexpected end of input while decoding SIB")
            }
        }

        /// Decodes displacement based on the addressing mode.
        fn decode_displacement(&mut self, mode: u8) -> Result<i64, &'static str> {
            match mode {
                0b00 => Ok(0),
                0b01 => Ok(self.decode_immediate(1)? as i8 as i64),
                0b10 => Ok(self.decode_immediate(4)? as i32 as i64),
                _ => Err("Invalid displacement mode"),
            }
        }

        /// Decodes an immediate value of given size (in bytes).
        fn decode_immediate(&mut self, size: usize) -> Result<u64, &'static str> {
            let mut value = 0u64;
            for i in 0..size {
                if let Some(byte) = self.next_byte() {
                    value |= (byte as u64) << (8 * i);
                } else {
                    return Err("Unexpected end of input while decoding immediate");
                }
            }
            Ok(value)
        }

        /// Decodes an operand based on ModR/M, SIB, and displacement.
        fn decode_operand(&mut self, mode: u8, reg: u8, rm: u8) -> Result<Operand, &'static str> {
            match mode {
                0b11 => Ok(Operand::Register(register_name(rm, self.rex))),
                _ => {
                    let mut address = String::new();
                    let (base, index, scale) = if rm == 0b100 && mode != 0b11 {
                        // SIB byte is present and not register-direct addressing
                        let (sib_scale, sib_index, sib_base) = self.decode_sib()?;
                        let scale_factor = 1 << sib_scale;
                        let index_reg = if sib_index != 0b100 {
                            register_name(sib_index, self.rex)
                        } else {
                            String::new()
                        };
                        let base_reg = if sib_base != 0b101 || mode != 0b00 {
                            register_name(sib_base, self.rex)
                        } else {
                            String::new()
                        };
                        (base_reg, index_reg, scale_factor)
                    } else {
                        (register_name(rm, self.rex), String::new(), 1)
                    };

                    if !base.is_empty() {
                        address.push_str(&base);
                    }

                    if !index.is_empty() {
                        if !address.is_empty() {
                            address.push_str(" + ");
                        }
                        address.push_str(&format!("{}*{}", index, scale));
                    }

                    let displacement = self.decode_displacement(mode)?;
                    if displacement != 0 {
                        if !address.is_empty() {
                            address.push_str(" + ");
                        }
                        address.push_str(&format!("{}", displacement));
                    }

                    Ok(Operand::Memory(format!("[{}]", address)))
                }
            }
        }
    }

    /// Maps register numbers to their names based on REX prefixes and operand sizes.
    fn register_name(reg: u8, rex: Option<u8>) -> String {
        let rex_b = rex.map(|r| (r & 0b0001) != 0).unwrap_or(false);
        let rex_r = rex.map(|r| (r & 0b0100) != 0).unwrap_or(false);
        let rex_x = rex.map(|r| (r & 0b0010) != 0).unwrap_or(false);
        let rex_w = rex.map(|r| (r & 0b1000) != 0).unwrap_or(false);

        // General-purpose registers
        let general_regs = [
            "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
            "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
        ];

        // 64-bit or 32-bit based on REX.W
        let wide = rex_w;

        if reg < general_regs.len() as u8 {
            let reg_base = if rex_b { 8 } else { 0 };
            let reg_str = general_regs[(reg + reg_base) as usize % general_regs.len()];
            if wide {
                reg_str.to_string()
            } else {
                if reg < 8 {
                    let low_regs = ["eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"];
                    low_regs[reg as usize].to_string()
                } else {
                    let low_regs = ["r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"];
                    low_regs[(reg - 8) as usize].to_string()
                }
            }
        } else {
            "unknown".to_string()
        }
    }

    /// Determines the operand size based on the decoder's current state.
    fn operand_size(decoder: &Decoder) -> usize {
        decoder.operand_size
    }

    /// Represents the size of the instruction based on its prefixes.
    fn address_size(decoder: &Decoder) -> usize {
        decoder.address_size
    }