Created
November 11, 2024 02:50
-
-
Save flippingbitss/c4eacf789e526fb500fae8c116fefcc0 to your computer and use it in GitHub Desktop.
MOV instruction decoding on 8086 for computerenhance.com
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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