//! Internal abstraction of all 8086 registers for disassembly. use crate::{disasm::DisasmError, operands::Operand}; use core::fmt; #[derive(Debug, Clone, PartialEq, Eq)] #[allow(dead_code)] /// Registers of a 8086 processor pub enum Register { // 8 bit // low bytes AL, CL, DL, BL, // high bytes AH, CH, DH, BH, // 16 bit AX, // accumulator CX, // counter DX, // data BX, // base SP, // stack pointer BP, // base pointer SI, // source index DI, // base index } /// Selector for Register or Segment Register pub type RegisterId = u8; #[allow(dead_code)] impl Register { /// Find the register corresponding to the 8086 bytecode ID pub fn by_id(id: Operand) -> Result { match id { Operand::Byte(b) => match b { 0b000 => Ok(Self::AL), 0b001 => Ok(Self::CL), 0b010 => Ok(Self::DL), 0b011 => Ok(Self::BL), 0b100 => Ok(Self::AH), 0b101 => Ok(Self::CH), 0b110 => Ok(Self::DH), 0b111 => Ok(Self::BH), _ => Err(DisasmError::UnknownRegister(b as usize)), }, Operand::Word(w) => match w { 0b000 => Ok(Self::AX), 0b001 => Ok(Self::CX), 0b010 => Ok(Self::DX), 0b011 => Ok(Self::BX), 0b100 => Ok(Self::SP), 0b101 => Ok(Self::BP), 0b110 => Ok(Self::SI), 0b111 => Ok(Self::DI), _ => Err(DisasmError::UnknownRegister(w as usize)), }, } } } impl fmt::Display for Register { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::AX => write!(f, "%ax"), Self::BX => write!(f, "%bx"), Self::CX => write!(f, "%cx"), Self::DX => write!(f, "%dx"), Self::AH => write!(f, "%ah"), Self::AL => write!(f, "%al"), Self::BL => write!(f, "%bl"), Self::BH => write!(f, "%bh"), Self::CH => write!(f, "%ch"), Self::CL => write!(f, "%cl"), Self::DH => write!(f, "%dh"), Self::DL => write!(f, "%dl"), Self::DI => write!(f, "%di"), Self::SI => write!(f, "%si"), Self::BP => write!(f, "%bp"), Self::SP => write!(f, "%sp"), } } } /// Segment Registers of a 8086 processor #[derive(Debug, Clone, PartialEq, Eq)] #[allow(dead_code)] pub enum SegmentRegister { DS, ES, SS, CS, } #[allow(dead_code)] impl SegmentRegister { /// Find the SRegister corresponding to the 8086 bytecode ID pub fn by_id(id: u8) -> Result { match id { 0x00 => Ok(Self::ES), 0x01 => Ok(Self::CS), 0x10 => Ok(Self::SS), 0x11 => Ok(Self::DS), _ => Err(DisasmError::UnknownRegister(id as usize)), } } } impl fmt::Display for SegmentRegister { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::DS => write!(f, "%ds"), Self::ES => write!(f, "%es"), Self::SS => write!(f, "%ss"), Self::CS => write!(f, "%cs"), } } }