Files
8086-rs/src/register.rs
2025-05-25 21:20:12 +09:00

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"),
}
}
}