diff --git a/src/disasm.rs b/src/disasm.rs index e78ed2b..aa2e08d 100644 --- a/src/disasm.rs +++ b/src/disasm.rs @@ -2,7 +2,7 @@ use crate::aout::Aout; use crate::operands::{ - Byte, Displacement, IByte, IWord, MemoryIndex, ModRmTarget, Operand, Pointer, Word, + Byte, DWord, Displacement, IByte, IWord, MemoryIndex, ModRmTarget, Operand, Pointer, Word, }; use crate::register::{Register, RegisterId, SegmentRegister}; use crate::{ @@ -157,6 +157,21 @@ impl Disassembler { Ok(word + next_addr) } + /// Parse a pointer type. + pub fn parse_ptr(&mut self) -> Result { + log::debug!("Attempting to parse pointer at {} ...", self.offset); + let byte0 = self.parse_byte()?; + let byte1 = self.parse_byte()?; + let byte2 = self.parse_byte()?; + let byte3 = self.parse_byte()?; + + Ok(Pointer { + raw: DWord::from_le_bytes([byte0, byte1, byte2, byte3]), + segment: Word::from_le_bytes([byte0, byte1]), + offset: Word::from_le_bytes([byte2, byte3]), + }) + } + /// Takes in a modrm byte and returns mod, reg and r/m. fn deconstruct_modrm_byte(modrm: u8) -> (u8, u8, u8) { let mode = (modrm >> 6) & 0b11; @@ -375,7 +390,7 @@ impl Disassembler { /// 2 words parsed for a `Pointer` type. pub fn modrm_mp(&mut self) -> Result<(ModRmTarget, Pointer), DisasmError> { let (target, _) = self.parse_modrm_byte(Operand::Byte(0))?; - let ptr = Pointer::new(self)?; + let ptr = self.parse_ptr()?; Ok((target, ptr)) } @@ -594,7 +609,7 @@ impl Disassembler { 0x98 => Mnemonic::CBW, 0x99 => Mnemonic::CWD, - 0x9A => Mnemonic::CALL_p(Pointer::new(self)?), + 0x9A => Mnemonic::CALL_p(self.parse_ptr()?), 0x9B => Mnemonic::WAIT, @@ -714,7 +729,7 @@ impl Disassembler { 0xE8 => Mnemonic::CALL_v(self.parse_j_word()?), 0xE9 => Mnemonic::JMP_v(self.parse_j_word()?), - 0xEA => Mnemonic::JMP_p(Pointer::new(self)?), + 0xEA => Mnemonic::JMP_p(self.parse_ptr()?), 0xEB => Mnemonic::JMP_b(self.parse_j_byte()?), 0xEC => Mnemonic::IN_ALDX, @@ -763,9 +778,9 @@ impl Disassembler { 0b000 => Mnemonic::INC_Mod(target), 0b001 => Mnemonic::DEC_Mod(target), 0b010 => Mnemonic::CALL_Mod(target), - 0b011 => Mnemonic::CALL_Mp(target, Pointer::new(self)?), + 0b011 => Mnemonic::CALL_Mp(target, self.parse_ptr()?), 0b100 => Mnemonic::JMP_Mod(target), - 0b101 => Mnemonic::JMP_Mp(target, Pointer::new(self)?), + 0b101 => Mnemonic::JMP_Mp(target, self.parse_ptr()?), 0b110 => Mnemonic::PUSH_Mod(target), // 0b111 => unused _ => return Err(DisasmError::IllegalGroupMnemonic(5, reg)), diff --git a/src/operands.rs b/src/operands.rs index cca854f..7e85868 100644 --- a/src/operands.rs +++ b/src/operands.rs @@ -1,10 +1,7 @@ //! All types which a Mnemonic can have as some kind of operand. //! This includes things such as immediates, ModRM byte targets, etc. etc. -use crate::{ - disasm::{DisasmError, Disassembler}, - register::Register, -}; +use crate::register::Register; use core::fmt; pub type Byte = u8; // b @@ -139,37 +136,6 @@ pub struct Pointer { pub offset: Word, } -impl Pointer { - pub fn new(disasm: &mut Disassembler) -> Result { - log::debug!( - "Seeking 4 bytes ahead of current text offset... ({} + 4)", - disasm.offset - ); - let byte0 = disasm - .text - .get(disasm.offset) - .ok_or(DisasmError::ReadBeyondTextSection(disasm.clone()))?; - let byte1 = disasm - .text - .get(disasm.offset + 1) - .ok_or(DisasmError::ReadBeyondTextSection(disasm.clone()))?; - let byte2 = disasm - .text - .get(disasm.offset + 2) - .ok_or(DisasmError::ReadBeyondTextSection(disasm.clone()))?; - let byte3 = disasm - .text - .get(disasm.offset + 3) - .ok_or(DisasmError::ReadBeyondTextSection(disasm.clone()))?; - - Ok(Pointer { - raw: DWord::from_le_bytes([*byte0, *byte1, *byte2, *byte3]), - segment: disasm.parse_word()?, - offset: disasm.parse_word()?, - }) - } -} - impl std::fmt::Display for Pointer { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "[{:#04x}] ({}:{})", self.raw, self.segment, self.offset)