ft: initial disasm of example data

This only contains two instructions of which I know
the correct output.
This commit is contained in:
2025-05-07 15:48:44 +09:00
commit 2af4578c8b
8 changed files with 804 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

403
Cargo.lock generated Normal file
View File

@@ -0,0 +1,403 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys",
]
[[package]]
name = "clap"
version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "env"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc95de49ad098572c02d3fbf368c9a020bfff5ae78483685b77f51d8a7e9486d"
dependencies = [
"num_threads",
]
[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"jiff",
"log",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "jiff"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd"
dependencies = [
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde",
]
[[package]]
name = "jiff-static"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "libc"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "mimix-8086-rs"
version = "0.1.0"
dependencies = [
"clap",
"env",
"env_logger",
"log",
]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

10
Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "mimix-8086-rs"
version = "0.1.0"
edition = "2024"
[dependencies]
clap = { version = "4.5.37", features = ["derive"] }
env = "1.0.1"
env_logger = "0.11.8"
log = "0.4.27"

62
src/aout.rs Normal file
View File

@@ -0,0 +1,62 @@
use std::ffi::{c_uchar, c_ushort};
#[allow(non_camel_case_types)]
pub type c_long = i32; // we use a a.out with 32 byte
#[derive(Debug)]
#[allow(dead_code)]
pub struct Aout {
pub header: Header,
pub text: Vec<u8>,
pub data: Vec<u8>,
}
impl Aout {
pub fn new(buf: Vec<u8>) -> Self {
let hdr = Header {
magic: [buf[0], buf[1]],
flags: buf[2],
cpu: buf[3],
hdrlen: buf[4],
unused: buf[5],
version: c_ushort::from_be_bytes([buf[6], buf[7]]),
text: c_long::from_le_bytes([buf[8], buf[9], buf[10], buf[11]]),
data: c_long::from_le_bytes([buf[12], buf[13], buf[14], buf[15]]),
bss: c_long::from_le_bytes([buf[16], buf[17], buf[18], buf[19]]),
entry: c_long::from_le_bytes([buf[20], buf[21], buf[22], buf[23]]),
total: c_long::from_le_bytes([buf[24], buf[25], buf[26], buf[27]]),
syms: c_long::from_le_bytes([buf[28], buf[29], buf[30], buf[31]]),
};
let text_start = hdr.hdrlen as usize;
let text_end = text_start + hdr.text as usize;
let data_start = text_end + 1;
let data_end = data_start + hdr.data as usize;
let text_section = &buf[text_start..text_end];
let data_section = &buf[data_start..data_end];
Aout {
header: hdr,
text: Vec::from(text_section),
data: Vec::from(data_section),
}
}
}
#[derive(Debug)]
#[allow(dead_code)]
pub struct Header {
pub magic: [c_uchar; 2], // magic number
pub flags: c_uchar, // flags, see below
pub cpu: c_uchar, // cpu id
pub hdrlen: c_uchar, // length of header
pub unused: c_uchar, // reserved for future use
pub version: c_ushort, // version stamp
pub text: c_long, // size of text segment in bytes
pub data: c_long, // size of data segment in bytes
pub bss: c_long, // size of bss segment in bytes
pub entry: c_long, // entry point
pub total: c_long, // total memory allocated
pub syms: c_long, // size of symbol table
}

1
src/decode.rs Normal file
View File

@@ -0,0 +1 @@

103
src/disasm.rs Normal file
View File

@@ -0,0 +1,103 @@
use core::fmt;
use std::{fs::File, io::Read, process::exit};
use crate::aout::Aout;
use crate::{
Args,
instructions::{ImmediateByte, ImmediateWord, Instruction, MetaInstruction, Register},
};
#[derive(Debug)]
pub enum DisasmError {
NoFile(Option<String>),
IoError(std::io::Error),
}
impl From<std::io::Error> for DisasmError {
fn from(error: std::io::Error) -> Self {
DisasmError::IoError(error)
}
}
impl fmt::Display for DisasmError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DisasmError::NoFile(msg) => write!(f, "No file error: {:?}", msg),
DisasmError::IoError(msg) => write!(f, "{}", msg),
}
}
}
/// Disassemble the binary in `path` into a vector of instructions
/// This function just calls all other
pub fn disasm(args: &Args) -> Result<Vec<MetaInstruction>, DisasmError> {
let contents = path_to_buf(args)?;
let aout = Aout::new(contents);
// XXX: 00 is just 0, maybe this could be a problem?
log::debug!("{:?}", aout);
let instructions = decode_instructions(&aout)?;
Ok(instructions)
}
/// Read a filepath into a buffer
fn path_to_buf(args: &Args) -> Result<Vec<u8>, DisasmError> {
let path = args
.path
.clone()
.ok_or(DisasmError::NoFile(args.path.clone()))?;
let mut file = File::open(path)?;
let mut buf = Vec::new();
file.read_to_end(&mut buf)?;
Ok(buf)
}
/// Decode instructions from the text section of the provided binary
fn decode_instructions(aout: &Aout) -> Result<Vec<MetaInstruction>, DisasmError> {
// naive approach:
// 1. read byte
// 2. pattern match to see which instruction it is
// 3. read as many bytes as this instruction needs (registers, immidiates, ...)
// repeat until no bytes left
let instructions = Vec::new();
let mut offset = 0;
let text = &aout.text;
while offset < aout.text.len() {
let mut instr = MetaInstruction::new();
instr.start = offset;
let opcode = text[offset];
match opcode {
// 0x00 => {} // ADD
// INT
0xCD => {
instr.take_n_bytes(2, &mut offset, text);
instr.instruction = Instruction::INT(ImmediateByte(instr.raw[1]));
}
// MOV
0xBB => {
instr.take_n_bytes(3, &mut offset, text);
instr.instruction = Instruction::MOV_RI(
Register::BX,
ImmediateWord(u16::from_le_bytes([instr.raw[1], instr.raw[2]])),
);
}
_ => {
eprintln!("Encountered unknown instruction '0x{:x}'", opcode);
eprintln!("Offset might be misaligned and data is being interpreted.");
eprintln!("Existing to avoid further misinterpretation...");
exit(1);
}
};
println!("{}", instr);
// dbg!(&instr);
}
Ok(instructions)
}

183
src/instructions.rs Normal file
View File

@@ -0,0 +1,183 @@
use core::fmt;
pub type MemAddress = u8;
#[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
}
impl MetaInstruction {
pub fn new() -> Self {
MetaInstruction {
start: 0,
size: 0,
raw: Vec::new(),
instruction: Instruction::NOP(),
}
}
/// Parse n bytes from text section and advance offet.
/// Used to get the operands.
pub fn take_n_bytes(&mut self, size: usize, offset: &mut usize, text: &Vec<u8>) {
self.size = size;
self.raw = text[*offset as usize..]
.iter()
.take(size)
.cloned()
.collect();
*offset += size;
}
}
impl fmt::Display for MetaInstruction {
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)]
#[allow(dead_code, non_camel_case_types)]
pub enum Instruction {
NOP(),
// ADD
ADD_RM(Register, Memory),
ADD_MR(Memory, Register),
ADD_RR(Register, Register),
ADD_MI(Memory, ImmediateByte),
ADD_RI(Register, ImmediateByte),
// MOV
MOV_RM(Register, Memory),
MOV_MR(Memory, Register),
MOV_RR(Register, Register),
MOV_MI(Memory, ImmediateByte),
MOV_RI(Register, ImmediateWord),
MOV_SM(SRegister, Memory),
MOV_MS(Memory, SRegister),
MOV_RS(Register, SRegister),
MOV_SR(SRegister, Register),
// INT
INT(ImmediateByte),
}
impl fmt::Display for Instruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::INT(byte) => write!(f, "INT, {:x}", byte),
Self::MOV_RI(reg, word) => write!(f, "MOV {}, {:04x}", reg, word),
_ => write!(f, "display not yet implemented"),
}
}
}
// Types for operand encoding
#[derive(Debug)]
pub struct Memory(pub MemAddress);
#[derive(Debug)]
pub struct ImmediateByte(pub u8);
#[derive(Debug)]
pub struct ImmediateWord(pub u16);
// ... and the displays for all of them
impl fmt::Display for Memory {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Display for ImmediateByte {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::LowerHex for ImmediateByte {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.0, f)
}
}
impl fmt::Display for ImmediateWord {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::LowerHex for ImmediateWord {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.0, f)
}
}
/// Registers of a 8086 processor
#[derive(Debug)]
#[allow(dead_code)]
pub enum Register {
AX,
BX,
CX,
DX,
AH,
AL,
BL,
BH,
CH,
CL,
DH,
DL,
DI,
SI,
BP,
SP,
}
impl fmt::Display for Register {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::AX => write!(f, "AX"),
Self::BX => write!(f, "BX"),
Self::CX => write!(f, "CX"),
Self::DX => write!(f, "DX"),
Self::AH => write!(f, "AH"),
Self::AL => write!(f, "AL"),
Self::BL => write!(f, "BL"),
Self::BH => write!(f, "BH"),
Self::CH => write!(f, "CH"),
Self::CL => write!(f, "CL"),
Self::DH => write!(f, "DH"),
Self::DL => write!(f, "DL"),
Self::DI => write!(f, "DI"),
Self::SI => write!(f, "SI"),
Self::BP => write!(f, "BP"),
Self::SP => write!(f, "SP"),
}
}
}
/// SRegisters of a 8086 processor
#[derive(Debug)]
#[allow(dead_code)]
pub enum SRegister {
DS,
ES,
SS,
CS,
}
impl fmt::Display for SRegister {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::DS => write!(f, "DS"),
Self::ES => write!(f, "ES"),
Self::SS => write!(f, "SS"),
Self::CS => write!(f, "CS"),
}
}
}

41
src/main.rs Normal file
View File

@@ -0,0 +1,41 @@
use clap::{Parser, Subcommand};
mod aout;
mod decode;
mod disasm;
mod instructions;
#[derive(Subcommand, Debug)]
enum Command {
/// Disassemble the binary into 8086 instructions
Disasm,
/// Interpret the binary as 8086 Minix
Interpret,
}
/// Simple prgram to diasm and interpret Minix binaries
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
#[command(subcommand)]
command: Command,
/// Path of the binary
#[arg(short, long, global = true)]
path: Option<String>,
}
fn main() {
env_logger::init();
let args = Args::parse();
log::debug!("{:?}", args);
match args.command {
Command::Disasm => {
let _instructions = disasm::disasm(&args).unwrap();
}
_ => panic!("Command not yet implemented"),
}
}