This repository has been archived by the owner on Aug 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: general improvement + sub/cmp/and/or...
- Loading branch information
Showing
15 changed files
with
615 additions
and
205 deletions.
There are no files selected for viewing
This file contains 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
This file was deleted.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
use crate::disassembler::instruction::Operand; | ||
|
||
#[derive(Debug, PartialEq)] | ||
pub enum IR { | ||
Mov { dest: Operand, src: Operand }, | ||
Int { int_type: u8 }, | ||
Add { dest: Operand, src: Operand }, | ||
Sub { dest: Operand, src: Operand }, | ||
Ssb { dest: Operand, src: Operand }, | ||
Cmp { dest: Operand, src: Operand }, | ||
And { dest: Operand, src: Operand }, | ||
Or { dest: Operand, src: Operand }, | ||
Xor { dest: Operand, src: Operand }, | ||
Lea { dest: Operand, src: Operand }, | ||
Lds { dest: Operand, src: Operand }, | ||
Les { dest: Operand, src: Operand }, | ||
} | ||
|
||
impl std::fmt::Display for IR { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
match self { | ||
IR::Mov { dest, src } => write!(f, "mov {}, {}", dest, src), | ||
IR::Int { int_type } => { | ||
if *int_type == 3 { | ||
write!(f, "int") | ||
} else { | ||
write!(f, "int {:02x}", int_type) | ||
} | ||
} | ||
IR::Add { dest, src } => write!(f, "add {}, {}", dest, src), | ||
IR::Sub { dest, src } => write!(f, "sub {}, {}", dest, src), | ||
IR::Ssb { dest, src } => write!(f, "ssb {}, {}", dest, src), | ||
IR::Cmp { dest, src } => write!(f, "cmp {}, {}", dest, src), | ||
IR::And { dest, src } => write!(f, "and {}, {}", dest, src), | ||
IR::Or { dest, src } => write!(f, "or {}, {}", dest, src), | ||
IR::Xor { dest, src } => write!(f, "xor {}, {}", dest, src), | ||
IR::Lea { dest, src } => write!(f, "lea {}, {}", dest, src), | ||
IR::Lds { dest, src } => write!(f, "lds {}, {}", dest, src), | ||
IR::Les { dest, src } => write!(f, "les {}, {}", dest, src), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, PartialEq)] | ||
pub struct Instruction { | ||
pub ir: IR, | ||
pub raw: Vec<u8>, | ||
} | ||
|
||
impl Instruction { | ||
pub fn new(ir: IR, raw: Vec<u8>) -> Self { | ||
Instruction { ir, raw } | ||
} | ||
} | ||
|
||
impl std::fmt::Display for Instruction { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!( | ||
f, | ||
"{}\t {}", | ||
self.raw | ||
.iter() | ||
.map(|b| format!("{:02x}", b)) | ||
.collect::<String>(), | ||
self.ir | ||
) | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pub mod instruction; | ||
pub mod operand; | ||
|
||
pub use instruction::{Instruction, IR}; | ||
pub use operand::Operand; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use crate::disassembler::{error::ParseError, Memory, Register}; | ||
|
||
#[derive(Debug, PartialEq)] | ||
pub enum Operand { | ||
Register(Register), | ||
Immediate(u8), | ||
LongImmediate(u16), | ||
Memory(Memory), | ||
} | ||
|
||
impl Operand { | ||
/// Parse a ModRM byte and return the corresponding operand. | ||
/// This can consume additional bytes from the instruction stream. | ||
pub fn parse_modrm( | ||
mod_: u8, | ||
rm: u8, | ||
bytes: &[u8], | ||
w: bool, | ||
) -> Result<(Operand, usize), ParseError> { | ||
match mod_ { | ||
0b11 => Ok((Operand::Register(Register::from(rm, w)), 0)), | ||
0b00 => { | ||
// Special case *: EA = disp-high;disp-low | ||
if rm == 0b110 { | ||
// parse next 2 bytes | ||
if bytes.len() < 3 { | ||
return Err(ParseError::UnexpectedEOF); | ||
} | ||
Ok(( | ||
Operand::Memory(Memory { | ||
base: None, | ||
index: None, | ||
disp_low: bytes[1], | ||
disp_high: Some(bytes[2]), | ||
}), | ||
2, | ||
)) | ||
} else { | ||
Ok(( | ||
Operand::Memory(Memory { | ||
base: Register::get_base(rm), | ||
index: Register::get_index(rm), | ||
disp_low: 0, | ||
disp_high: None, | ||
}), | ||
0, | ||
)) | ||
} | ||
} | ||
0b01 => { | ||
// parse next byte | ||
if bytes.len() < 2 { | ||
return Err(ParseError::UnexpectedEOF); | ||
} | ||
return Ok(( | ||
Operand::Memory(Memory { | ||
base: Register::get_base(rm), | ||
index: Register::get_index(rm), | ||
disp_low: bytes[1], | ||
disp_high: None, | ||
}), | ||
1, | ||
)); | ||
} | ||
0b10 => { | ||
// parse next 2 bytes | ||
if bytes.len() < 3 { | ||
return Err(ParseError::UnexpectedEOF); | ||
} | ||
return Ok(( | ||
Operand::Memory(Memory { | ||
base: Register::get_base(rm), | ||
index: Register::get_index(rm), | ||
disp_low: bytes[1], | ||
disp_high: Some(bytes[2]), | ||
}), | ||
2, | ||
)); | ||
} | ||
_ => Err(ParseError::InvalidModRM), | ||
} | ||
} | ||
} | ||
|
||
impl std::fmt::Display for Operand { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
match self { | ||
Operand::Register(r) => write!(f, "{}", r), | ||
Operand::Immediate(i) => write!(f, "{:02x}", i), | ||
Operand::LongImmediate(i) => write!(f, "{:04x}", i), | ||
Operand::Memory(mem) => write!(f, "{}", mem), | ||
} | ||
} | ||
} |
This file contains 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
This file contains 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
Oops, something went wrong.