fix: cleanup structs into correct files

This commit is contained in:
2025-05-08 10:05:09 +09:00
parent 849895a437
commit 1c7d3f3adc
5 changed files with 229 additions and 229 deletions

View File

@@ -1,76 +1,45 @@
use core::fmt;
use crate::disasm::Displacement;
pub type MemAddress = u8;
// b: 8, w: 16, v: 16 -> i just treat v and w the same, if nothing blows up
#[allow(non_camel_case_types)]
pub type b = u8;
#[allow(non_camel_case_types)]
pub type w = u16;
#[derive(Debug)]
#[allow(dead_code)]
/// A single 'line' of executable ASM is called a MetaInstruction, which
/// contains the `Instruction`, which will be executed, alongside some Meta
/// Informations.
pub struct MetaInstruction {
pub start: usize, // location of the instruction start
pub size: usize, // size of the instruction in bytes
pub raw: Vec<u8>, // raw value of instruction
pub instruction: Instruction, // actual instruction
/// A single 'line' of executable ASM is called an Instruction, which
/// contains the `Opcode` that will be executed, alongside its starting offset
/// and the raw parsed bytes
pub struct Instruction {
pub start: usize, // location of the instruction start
pub raw: Vec<u8>, // raw value of instruction
pub opcode: Opcode, // actual instruction
}
impl MetaInstruction {
impl Instruction {
pub fn new() -> Self {
MetaInstruction {
Instruction {
start: 0,
size: 0,
raw: Vec::new(),
instruction: Instruction::NOP(),
opcode: Opcode::NOP(),
}
}
}
impl fmt::Display for MetaInstruction {
impl fmt::Display for Instruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:04x}: ", self.start).unwrap();
for b in self.raw.iter() {
write!(f, "{:02x}", b).unwrap();
}
write!(f, "\t{}", self.instruction)
}
}
#[derive(Debug)]
pub struct MemoryIndex {
pub base: Option<Register>,
pub index: Option<Register>,
pub displacement: Option<Displacement>,
}
impl fmt::Display for MemoryIndex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.base {
Some(base) => match &self.index {
Some(index) => match &self.displacement {
Some(displacement) => write!(f, "[{}+{}+{}]", base, index, displacement),
None => write!(f, "[{}+{}]", base, index),
},
None => match &self.displacement {
Some(displacement) => write!(f, "[{}+{}]", base, displacement),
None => write!(f, "[{}]", base),
},
},
None => match &self.index {
Some(index) => match &self.displacement {
Some(displacement) => write!(f, "{}+{}", index, displacement),
None => write!(f, "[{}]", index),
},
None => panic!("Invalid MemoryIndex encountered"),
},
}
write!(f, "\t{}", self.opcode)
}
}
#[derive(Debug)]
#[allow(dead_code, non_camel_case_types)]
pub enum Instruction {
pub enum Opcode {
NOP(),
// ADD
ADD_EbGb(MemoryIndex, Register),
@@ -80,7 +49,7 @@ pub enum Instruction {
INT(ImmediateByte),
}
impl fmt::Display for Instruction {
impl fmt::Display for Opcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::INT(byte) => write!(f, "INT, {:x}", byte),
@@ -91,46 +60,6 @@ impl fmt::Display for Instruction {
}
}
// Types for operand encoding
#[derive(Debug)]
pub struct Memory(pub MemAddress);
// b: 8, w: 16, v: 16 -> i just treat v and w the same, if nothing blows up
#[derive(Debug)]
pub struct ImmediateByte(pub u8);
#[derive(Debug)]
pub struct ImmediateWord(pub u16);
// ... and the displays for all of them
macro_rules! impl_display {
($name:ident) => {
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
};
}
macro_rules! impl_display_and_lowerhex {
($name:ident) => {
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::fmt::LowerHex for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::LowerHex::fmt(&self.0, f)
}
}
};
}
impl_display!(Memory);
impl_display_and_lowerhex!(ImmediateByte);
impl_display_and_lowerhex!(ImmediateWord);
/// Registers of a 8086 processor
#[derive(Debug)]
#[allow(dead_code)]
@@ -236,3 +165,80 @@ impl fmt::Display for SegmentRegister {
}
}
}
/// An immediate byte value for an instruction.
#[derive(Debug)]
pub struct ImmediateByte(pub b);
/// An immediate word value for an instruction
#[derive(Debug)]
pub struct ImmediateWord(pub w);
macro_rules! impl_display_and_lowerhex {
($name:ident) => {
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::fmt::LowerHex for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::LowerHex::fmt(&self.0, f)
}
}
};
}
impl_display_and_lowerhex!(ImmediateByte);
impl_display_and_lowerhex!(ImmediateWord);
/// A memory index operand is usually created by ModRM bytes or words.
/// e.g. [bx+si]
#[derive(Debug)]
pub struct MemoryIndex {
pub base: Option<Register>,
pub index: Option<Register>,
pub displacement: Option<Displacement>,
}
impl fmt::Display for MemoryIndex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.base {
Some(base) => match &self.index {
Some(index) => match &self.displacement {
Some(displacement) => write!(f, "[{}+{}+{}]", base, index, displacement),
None => write!(f, "[{}+{}]", base, index),
},
None => match &self.displacement {
Some(displacement) => write!(f, "[{}+{}]", base, displacement),
None => write!(f, "[{}]", base),
},
},
None => match &self.index {
Some(index) => match &self.displacement {
Some(displacement) => write!(f, "{}+{}", index, displacement),
None => write!(f, "[{}]", index),
},
None => panic!("Invalid MemoryIndex encountered"),
},
}
}
}
#[derive(Debug)]
#[allow(dead_code)]
/// Displacement for ModRM
pub enum Displacement {
Byte(u8),
Word(u16),
}
impl fmt::Display for Displacement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Byte(byte) => write!(f, "{}", byte),
Self::Word(word) => write!(f, "{}", word),
}
}
}