124 lines
3.3 KiB
Rust
124 lines
3.3 KiB
Rust
//! 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<Self, DisasmError> {
|
|
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<Self, DisasmError> {
|
|
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"),
|
|
}
|
|
}
|
|
}
|