Skip to content

Instantly share code, notes, and snippets.

@flippingbitss
Created November 11, 2024 02:50
Show Gist options
  • Save flippingbitss/c4eacf789e526fb500fae8c116fefcc0 to your computer and use it in GitHub Desktop.
Save flippingbitss/c4eacf789e526fb500fae8c116fefcc0 to your computer and use it in GitHub Desktop.
MOV instruction decoding on 8086 for computerenhance.com
// mov ax, bx
// instruction - dest reg
// 6 bits(bit pattern for mov) - D W | MOD (2) - REG(3) - R/M(3)
use std::fmt::Display;
const REG_NAMES_R: [&str; 8] = ["al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"];
const REG_NAMES_W: [&str; 8] = ["ax", "cx", "dx", "bx", "sp", "bp", "si", "di"];
#[repr(u8)]
enum Mneumonic {
MOV,
}
impl Display for Mneumonic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MOV => write!(f, "mov"),
}
}
}
enum DecodeError {
UnknownMneumonic,
}
impl TryFrom<u8> for Mneumonic {
type Error = DecodeError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
let name = value & 0xFC; // clip D, W
match name {
0b10001000 => Ok(Mneumonic::MOV),
_ => return Err(DecodeError::UnknownMneumonic),
}
}
}
struct Inst {
name: Mneumonic,
dest: bool,
wide: bool,
modd: u8,
reg: u8,
rem: u8,
}
impl Display for Inst {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let names = if self.wide { REG_NAMES_W } else { REG_NAMES_R };
let dest_reg = if self.dest { self.reg } else { self.rem };
let src_reg = if !self.dest { self.reg } else { self.rem };
write!(
f,
"{} {}, {}",
self.name, names[dest_reg as usize], names[src_reg as usize]
)
}
}
fn decode(first: u8, sec: u8) -> Result<Inst, DecodeError> {
let name = Mneumonic::try_from(first)?;
let dest = (first & 0b10) > 0;
let wide = (first & 0b01) > 0;
let modd: u8 = 0b11; //reg to reg mode
let reg: u8 = (sec & 0b111000) >> 3;
let rem: u8 = sec & 0b000111;
Ok(Inst {
name,
dest,
wide,
modd,
reg,
rem,
})
}
fn main() -> Result<(), std::io::Error> {
let bytes = std::fs::read("many-moves")?;
for pair in bytes.chunks_exact(2) {
match pair {
&[f, s] => {
if let Ok(inst) = decode(f, s) {
println!("{}", inst);
} else {
println!("Unable to decode word {:b} | {:b}", f, s)
}
}
_ => unreachable!(),
}
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment