fix: align pointer parsing with spec

Previously pointer parsing was completely wrong.
Now split into Pointer32 for immediates with
segment;offset and Pointer16 for short jumps, which
use DS or ES as segment and the Pointer16 value
as offset.
This commit is contained in:
2025-05-28 13:28:35 +09:00
parent 0893969f4e
commit c396d33f76
3 changed files with 71 additions and 37 deletions

View File

@@ -1,7 +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::register::Register;
use crate::{disasm::DisasmError, register::Register};
use core::fmt;
pub type Byte = u8; // b
@@ -131,15 +131,52 @@ impl fmt::Display for MemoryIndex {
}
#[derive(Debug, Clone, PartialEq, Eq)]
/// 32-bit segment:offset pointer (e.g. for CALL instruction)
pub struct Pointer {
/// 16-bit pointer for access, usually with a [`SegmentRegister`] as segment
/// and [`Pointer16`] as offset.
pub struct Pointer16 {
pub word: Word,
}
impl std::fmt::Display for Pointer16 {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "ptr [{:#04x}]", self.word)
}
}
impl TryFrom<ModRmTarget> for Pointer16 {
type Error = DisasmError;
fn try_from(target: ModRmTarget) -> Result<Self, Self::Error> {
match target {
ModRmTarget::Memory(mem) => match mem.displacement {
Some(disp) => match disp {
Displacement::IWord(word) => Ok(Pointer16 { word: word as Word }),
_ => {
return Err(DisasmError::IllegalOperand("Word expected".into()));
}
},
_ => {
return Err(DisasmError::IllegalOperand("Displacement expected".into()));
}
},
_ => {
return Err(DisasmError::IllegalOperand("MemoryIndex expected".into()));
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
/// 32-bit segment:offset pointer for long jumps.
/// Both [`Word`]s are immediately encoded after the instruction
pub struct Pointer32 {
pub raw: DWord,
pub segment: Word,
pub offset: Word,
}
impl std::fmt::Display for Pointer {
impl std::fmt::Display for Pointer32 {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "[{:#04x}] ({}:{})", self.raw, self.segment, self.offset)
write!(f, "{:#04x}:{:#04x}", self.segment, self.offset)
}
}