fix: fix displacement parsing
1. correctly return when only displacement in modrm mem adressing Previously the disassmbler wouldn't stop if only a displacement value should be used without any base or offset index. 2. Displacement can be negative, so use the signed version where applicable
This commit is contained in:
@@ -3,7 +3,9 @@ use core::fmt;
|
||||
use crate::register::{Register, SegmentRegister};
|
||||
|
||||
pub type Byte = u8; // b
|
||||
pub type IByte = i8; // used for displacements of memory access
|
||||
pub type Word = u16; // w or v
|
||||
pub type IWord = i16; // used for displacement of memory access
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
@@ -79,8 +81,8 @@ pub enum Mnemonic {
|
||||
// ADD
|
||||
ADD_FromReg(ModRmTarget, Register), // From Register into either Memory or Register
|
||||
ADD_ToReg(ModRmTarget, Register), // From either Memory or Register into Reigster
|
||||
ADD_Ib(ModRmTarget, Byte), // From Immediate into either Memory or Register
|
||||
ADD_Iv(ModRmTarget, Word), // From Immediate into either Memory or Register
|
||||
ADD_Ib(ModRmTarget, IByte), // From Immediate into either Memory or Register
|
||||
ADD_Iv(ModRmTarget, IWord), // From Immediate into either Memory or Register
|
||||
ADD_ALIb(Byte),
|
||||
ADD_AXIv(Word),
|
||||
// PUSH
|
||||
@@ -94,29 +96,29 @@ pub enum Mnemonic {
|
||||
// OR
|
||||
OR_FromReg(ModRmTarget, Register),
|
||||
OR_ToReg(ModRmTarget, Register),
|
||||
OR_Ib(ModRmTarget, Byte),
|
||||
OR_Iv(ModRmTarget, Word),
|
||||
OR_Ib(ModRmTarget, IByte),
|
||||
OR_Iv(ModRmTarget, IWord),
|
||||
OR_ALIb(Byte),
|
||||
OR_AXIv(Word),
|
||||
// ADC
|
||||
ADC_FromReg(ModRmTarget, Register),
|
||||
ADC_ToReg(ModRmTarget, Register),
|
||||
ADC_Ib(ModRmTarget, Byte),
|
||||
ADC_Iv(ModRmTarget, Word),
|
||||
ADC_Ib(ModRmTarget, IByte),
|
||||
ADC_Iv(ModRmTarget, IWord),
|
||||
ADC_ALIb(Byte),
|
||||
ADC_AXIv(Word),
|
||||
// SBB
|
||||
SBB_FromReg(ModRmTarget, Register),
|
||||
SBB_ToReg(ModRmTarget, Register),
|
||||
SBB_Ib(ModRmTarget, Byte),
|
||||
SBB_Iv(ModRmTarget, Word),
|
||||
SBB_Ib(ModRmTarget, IByte),
|
||||
SBB_Iv(ModRmTarget, IWord),
|
||||
SBB_ALIb(Byte),
|
||||
SBB_AXIv(Word),
|
||||
// AND
|
||||
AND_FromReg(ModRmTarget, Register),
|
||||
AND_ToReg(ModRmTarget, Register),
|
||||
AND_Ib(ModRmTarget, Byte),
|
||||
AND_Iv(ModRmTarget, Word),
|
||||
AND_Ib(ModRmTarget, IByte),
|
||||
AND_Iv(ModRmTarget, IWord),
|
||||
AND_ALIb(Byte),
|
||||
AND_AXIv(Word),
|
||||
// Override
|
||||
@@ -129,22 +131,22 @@ pub enum Mnemonic {
|
||||
// SUB
|
||||
SUB_FromReg(ModRmTarget, Register),
|
||||
SUB_ToReg(ModRmTarget, Register),
|
||||
SUB_Ib(ModRmTarget, Byte),
|
||||
SUB_Iv(ModRmTarget, Word),
|
||||
SUB_Ib(ModRmTarget, IByte),
|
||||
SUB_Iv(ModRmTarget, IWord),
|
||||
SUB_ALIb(Byte),
|
||||
SUB_AXIv(Word),
|
||||
// XOR
|
||||
XOR_FromReg(ModRmTarget, Register),
|
||||
XOR_ToReg(ModRmTarget, Register),
|
||||
XOR_Ib(ModRmTarget, Byte),
|
||||
XOR_Iv(ModRmTarget, Word),
|
||||
XOR_Ib(ModRmTarget, IByte),
|
||||
XOR_Iv(ModRmTarget, IWord),
|
||||
XOR_ALIb(Byte),
|
||||
XOR_AXIv(Word),
|
||||
// CMP
|
||||
CMP_FromReg(ModRmTarget, Register),
|
||||
CMP_ToReg(ModRmTarget, Register),
|
||||
CMP_Ib(ModRmTarget, Byte),
|
||||
CMP_Iv(ModRmTarget, Word),
|
||||
CMP_Ib(ModRmTarget, IByte),
|
||||
CMP_Iv(ModRmTarget, IWord),
|
||||
CMP_ALIb(Byte),
|
||||
CMP_AXIv(Word),
|
||||
// INC
|
||||
@@ -307,13 +309,29 @@ impl std::fmt::Display for ModRmTarget {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// Displacements are signed versions of u8 and u16.
|
||||
pub enum Displacement {
|
||||
IByte(i8),
|
||||
IWord(i16),
|
||||
}
|
||||
|
||||
impl fmt::LowerHex for Displacement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::IByte(b) => fmt::LowerHex::fmt(b, f),
|
||||
Self::IWord(v) => fmt::LowerHex::fmt(v, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A memory index operand is usually created by ModRM bytes or words.
|
||||
/// e.g. [bx+si]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MemoryIndex {
|
||||
pub base: Option<Register>,
|
||||
pub index: Option<Register>,
|
||||
pub displacement: Option<Operand>,
|
||||
pub displacement: Option<Displacement>,
|
||||
}
|
||||
|
||||
impl fmt::Display for MemoryIndex {
|
||||
@@ -336,7 +354,10 @@ impl fmt::Display for MemoryIndex {
|
||||
Some(displacement) => write!(f, "[{}+{:04x}]", index, displacement),
|
||||
None => write!(f, "[{}]", index),
|
||||
},
|
||||
None => panic!("Invalid MemoryIndex encountered"),
|
||||
None => match &self.displacement {
|
||||
Some(displacement) => write!(f, "[{:04x}]", displacement),
|
||||
None => panic!("Memory Index without base, index and displacement"),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user