add disassembly & display functions

This commit is contained in:
Michael Sippel 2024-05-12 04:21:17 +02:00
parent 7efee58c4d
commit 4fb80fe158
Signed by: senvas
GPG key ID: F96CF119C34B64A6
3 changed files with 62 additions and 1 deletions

View file

@ -5,7 +5,7 @@ use {
} }
}; };
#[derive(Clone)] #[derive(Clone, Debug)]
pub enum AssemblyWord { pub enum AssemblyWord {
Symbol( LinkAddr ), Symbol( LinkAddr ),
Lit( VM_Word ) Lit( VM_Word )
@ -25,6 +25,38 @@ impl AssemblyWord {
} }
} }
pub fn disassemble(bytecode: &Vec< AssemblyWord >) -> Vec< String > {
let mut words = bytecode.iter();
let mut result = Vec::new();
let mut remaining_params = 0;
while let Some(w) = words.next() {
match w {
AssemblyWord::Symbol( addr ) => {
result.push( format!("{}", addr) );
remaining_params -= 1;
}
AssemblyWord::Lit(w) => {
if remaining_params == 0 {
if *w < 18 {
let inst : VM_Instruction = unsafe { std::mem::transmute(*w) };
result.push(format!("{:?}", inst));
remaining_params = inst.param_length();
} else {
result.push(format!("invalid opcode {}", w));
}
} else {
remaining_params -= 1;
result.push(format!("{}", w));
}
}
}
}
result
}
pub struct Assembler { pub struct Assembler {
words: Vec< AssemblyWord >, words: Vec< AssemblyWord >,
} }

View file

@ -12,6 +12,21 @@ pub enum LinkAddr {
} }
} }
impl std::fmt::Display for LinkAddr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
LinkAddr::Absolute(addr) =>
write!(f, "{:x}", addr),
LinkAddr::Relative{ symbol, offset } =>
if *offset == 0 {
write!(f, "{}", symbol)
} else {
write!(f, "{}+{:x}", symbol, offset)
}
}
}
}
pub struct Section { pub struct Section {
addr: VM_Word, addr: VM_Word,
data: Vec< AssemblyWord > data: Vec< AssemblyWord >

View file

@ -12,6 +12,20 @@ pub enum VM_Instruction {
BitwiseNot, BitwiseNot,
} }
impl VM_Instruction {
pub fn param_length(&self) -> usize {
match self {
VM_Instruction::Jmp |
VM_Instruction::Call |
VM_Instruction::Branch |
VM_Instruction::Lit => {
1
},
_ => 0
}
}
}
pub struct VM { pub struct VM {
pub data_stack: Vec< VM_Word >, pub data_stack: Vec< VM_Word >,
pub call_stack: Vec< VM_Word >, pub call_stack: Vec< VM_Word >,