add disassembly & display functions
This commit is contained in:
parent
7efee58c4d
commit
4fb80fe158
3 changed files with 62 additions and 1 deletions
|
@ -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 >,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 >
|
||||||
|
|
14
src/vm.rs
14
src/vm.rs
|
@ -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 >,
|
||||||
|
|
Loading…
Reference in a new issue