Implement decoding logic for all
disassembler.rs
use crate::instruction::Instruction;
use crate::parser::utilities::{read_u16_le, read_u32_le, read_i8, read_i16_le, read_i32_le};
use colored::*;

const REG8: [&str; 8] = ["AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"];
const REG16: [&str; 8] = ["AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI"];
const REG32: [&str; 8] = ["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"];

pub fn disassemble(data: &[u8]) -> Result<Vec<Instruction>, String> {
    let mut instructions = Vec::new();
    let mut offset = 0;

    while offset < data.len() {
        let (instruction, size) = decode_instruction(data, offset)?;
        instructions.push(instruction);
        offset += size;
    }

    Ok(instructions)
}

fn decode_instruction(data: &[u8], offset: usize) -> Result<(Instruction, usize), String> {
    if offset >= data.len() {
        return Err("Unexpected end of data".to_string());
    }

    let mut prefix = 0;
    let mut current_offset = offset;

    // Handle prefixes
    while current_offset < data.len() {
        match data[current_offset] {
            0x66 => prefix |= 1, // Operand size override
            0x67 => prefix |= 2, // Address size override
            0xF0 => prefix |= 4, // LOCK prefix
            0xF2 => prefix |= 8, // REPNE/REPNZ prefix
            0xF3 => prefix |= 16, // REP/REPE/REPZ prefix
            _ => break,
        }
        current_offset += 1;
    }

    if current_offset >= data.len() {
        return Err("Unexpected end of data".to_string());
    }

    let opcode = data[current_offset];
    let (mnemonic, operands, size) = match opcode {
        0x00..=0x03 => decode_add(data, current_offset, prefix)?,
        0x04 | 0x05 => decode_add_al_ax_eax(data, current_offset, prefix)?,
        0x08..=0x0B => decode_or(data, current_offset, prefix)?,
        0x0C | 0x0D => decode_or_al_ax_eax(data, current_offset, prefix)?,
        0x10..=0x13 => decode_adc(data, current_offset, prefix)?,
        0x14 | 0x15 => decode_adc_al_ax_eax(data, current_offset, prefix)?,
        0x20..=0x23 => decode_and(data, current_offset, prefix)?,
        0x24 | 0x25 => decode_and_al_ax_eax(data, current_offset, prefix)?,
        0x28..=0x2B => decode_sub(data, current_offset, prefix)?,
        0x2C | 0x2D => decode_sub_al_ax_eax(data, current_offset, prefix)?,
        0x30..=0x33 => decode_xor(data, current_offset, prefix)?,
        0x34 | 0x35 => decode_xor_al_ax_eax(data, current_offset, prefix)?,
        0x38..=0x3B => decode_cmp(data, current_offset, prefix)?,
        0x3C | 0x3D => decode_cmp_al_ax_eax(data, current_offset, prefix)?,
        0x40..=0x47 => decode_inc_reg(data, current_offset, prefix)?,
        0x48..=0x4F => decode_dec_reg(data, current_offset, prefix)?,
        0x50..=0x57 => decode_push_reg(data, current_offset, prefix)?,
        0x58..=0x5F => decode_pop_reg(data, current_offset, prefix)?,
        0x68 => decode_push_imm(data, current_offset, prefix)?,
        0x6A => decode_push_imm8(data, current_offset)?,
        0x70..=0x7F => decode_jcc_short(data, current_offset)?,
        0x80..=0x83 => decode_group1(data, current_offset, prefix)?,
        0x84 | 0x85 => decode_test(data, current_offset, prefix)?,
        0x86 | 0x87 => decode_xchg(data, current_offset, prefix)?,
        0x88..=0x8B => decode_mov(data, current_offset, prefix)?,
        0x8D => decode_lea(data, current_offset, prefix)?,
        0x8F => decode_pop_rm(data, current_offset, prefix)?,
        0x90 => ("NOP".to_string(), vec![], 1),
        0x91..=0x97 => decode_xchg_eax_reg(data, current_offset)?,
        0xB0..=0xB7 => decode_mov_reg8_imm8(data, current_offset)?,
        0xB8..=0xBF => decode_mov_reg_imm(data, current_offset, prefix)?,
        0xC3 => ("RET".to_string(), vec![], 1),
        0xC6 | 0xC7 => decode_mov_rm_imm(data, current_offset, prefix)?,
        0xE8 => decode_call_near(data, current_offset)?,
        0xE9 => decode_jmp_near(data, current_offset)?,
        0xEB => decode_jmp_short(data, current_offset)?,
        0xF6 | 0xF7 => decode_group3(data, current_offset, prefix)?,
        0xFF => decode_group5(data, current_offset, prefix)?,
        _ => (format!("DB 0x{:02X}", opcode), vec![], 1),
    };

    let instruction = Instruction {
        opcode,
        mnemonic,
        operands,
        bytes: data[offset..current_offset + size].to_vec(),
        address: offset,
    };

    Ok((instruction, current_offset - offset + size))
}

// Helper functions for decoding specific instruction groups

fn decode_add(data: &[u8], offset: usize, prefix: u8) -> Result<(String, Vec<String>, usize), String> {
    // Implement ADD decoding logic
    unimplemented!()
}

fn decode_add_al_ax_eax(data: &[u8], offset: usize, prefix: u8) -> Result<(String, Vec<String>, usize), String> {
    // Implement ADD AL/AX/EAX, imm8/imm16/imm32 decoding logic
    unimplemented!()
}

// Implement other decoding functions for different instruction groups...

fn decode_modrm(data: &[u8], offset: usize, prefix: u8) -> Result<(String, String, usize), String> {
    if offset + 1 >= data.len() {
        return Err("Unexpected end of data".to_string());
    }

    let modrm = data[offset];
    let mod_bits = modrm >> 6;
    let reg = (modrm >> 3) & 0x07;
    let rm = modrm & 0x07;

    let (src, dst, size) = match mod_bits {
        0b00 => {
            if rm == 0b100 {
                decode_sib(data, offset + 1, prefix)?
            } else if rm == 0b101 {
                let disp32 = read_i32_le(data, offset + 1).ok_or("Unexpected end of data")?;
                (format!("[0x{:08X}]", disp32), REG32[reg as usize].to_string(), 5)
            } else {
                (format!("[{}]", REG32[rm as usize]), REG32[reg as usize].to_string(), 1)
            }
        },
        0b01 => {
            let disp8 = read_i8(data, offset + 1).ok_or("Unexpected end of data")?;
            if rm == 0b100 {
                let (base, index, scale) = decode_sib(data, offset + 1, prefix)?;
                (format!("[{} + {} * {} + {}]", base, index, scale, disp8), REG32[reg as usize].to_string(), 3)
            } else {
                (format!("[{} + {}]", REG32[rm as usize], disp8), REG32[reg as usize].to_string(), 2)
            }
        },
        0b10 => {
            let disp32 = read_i32_le(data, offset + 1).ok_or("Unexpected end of data")?;
            if rm == 0b100 {
                let (base, index, scale) = decode_sib(data, offset + 1, prefix)?;
                (format!("[{} + {} * {} + {}]", base, index, scale, disp32), REG32[reg as usize].to_string(), 6)
            } else {
                (format!("[{} + {}]", REG32[rm as usize], disp32), REG32[reg as usize].to_string(), 5)
            }
        },
        0b11 => (REG32[rm as usize].to_string(), REG32[reg as usize].to_string(), 1),
        _ => unreachable!(),
    };

    Ok((src, dst, size.into()))
}

fn decode_sib(data: &[u8], offset: usize, prefix: u8) -> Result<(String, String, u8), String> {
    if offset >= data.len() {
        return Err("Unexpected end of data".to_string());
    }

    let sib = data[offset];
    let scale = 1 << (sib >> 6);
    let index = REG32[((sib >> 3) & 0x07) as usize];
    let base = REG32[(sib & 0x07) as usize];

    Ok((base.to_string(), index.to_string(), scale))
}

pub fn format_disassembly(instructions: &[Instruction]) -> String {
    instructions
        .iter()
        .map(|instr| {
            format!(
                "{}: {} {}{}",
                format!("{:04X}", instr.address).yellow(),
                instr.bytes.iter().map(|b| format!("{:02X}", b)).collect::<Vec<String>>().join(" ").cyan(),
                instr.mnemonic.green(),
                if instr.operands.is_empty() {
                    String::new()
                } else {
                    format!(" {}", instr.operands.join(", ").white())
                }
            )
        })
        .collect::<Vec<String>>()
        .join("\n")
}

instruction.rs:
use std::fmt;

#[derive(Debug, Clone)]
pub struct Instruction {
    pub opcode: u8,
    pub mnemonic: String,
    pub operands: Vec<String>,
    pub bytes: Vec<u8>,
    pub address: usize,
}

impl fmt::Display for Instruction {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{:04X}: {:10} {}",
            self.address,
            self.bytes.iter().map(|b| format!("{:02X}", b)).collect::<Vec<String>>().join(" "),
            self.mnemonic
        )?;
        if !self.operands.is_empty() {
            write!(f, " {}", self.operands.join(", "))?;
        }
        Ok(())
    }
}