chore: remove Immediate from Immediate::{Word, Byte, Operand}
It's already clear that its an Immediate value without the prefix.
This commit is contained in:
@@ -2,7 +2,7 @@ use core::fmt;
|
||||
use std::{fs::File, io::Read, process::exit};
|
||||
|
||||
use crate::aout::Aout;
|
||||
use crate::instructions::{ImmediateOperand, MemoryIndex, ModRmTarget, Pointer};
|
||||
use crate::instructions::{MemoryIndex, ModRmTarget, Operand, Pointer};
|
||||
use crate::register::{Register, RegisterId, SegmentRegister};
|
||||
use crate::{
|
||||
Args,
|
||||
@@ -108,7 +108,7 @@ impl Disassembler {
|
||||
|
||||
/// Parse a single modrm byte, return the resulting MemoryIndex and advance the offset.
|
||||
/// Returns the parsed modrm target and the source register
|
||||
pub fn parse_modrm_byte(&mut self, width: ImmediateOperand) -> (ModRmTarget, RegisterId) {
|
||||
pub fn parse_modrm_byte(&mut self, width: Operand) -> (ModRmTarget, RegisterId) {
|
||||
// advance to operand
|
||||
self.offset += 1;
|
||||
let modrm = self.text[self.offset];
|
||||
@@ -129,28 +129,26 @@ impl Disassembler {
|
||||
0b00 => {
|
||||
if rm == 0b110 {
|
||||
log::debug!("Additional word during ModRM parsing was read with mod 0.");
|
||||
displacement = Some(ImmediateOperand::Word(self.parse_word()));
|
||||
displacement = Some(Operand::Word(self.parse_word()));
|
||||
} else {
|
||||
displacement = None;
|
||||
}
|
||||
}
|
||||
0b01 => {
|
||||
log::debug!("Additional byte during ModRM parsing was read.");
|
||||
displacement = Some(ImmediateOperand::Byte(self.parse_byte()))
|
||||
displacement = Some(Operand::Byte(self.parse_byte()))
|
||||
}
|
||||
0b10 => {
|
||||
log::debug!("Additional word during ModRM parsing was read.");
|
||||
displacement = Some(ImmediateOperand::Word(self.parse_word()));
|
||||
displacement = Some(Operand::Word(self.parse_word()));
|
||||
}
|
||||
0b11 => {
|
||||
log::debug!("ModRM (0b{:b}) to/from Register (0b{:b})", rm, reg);
|
||||
// XXX: find a nicer way instead of using Byte(0) and Word(0)
|
||||
let target = match width {
|
||||
ImmediateOperand::Byte(_) => {
|
||||
ModRmTarget::Register(Register::by_id(ImmediateOperand::Byte(rm)))
|
||||
}
|
||||
ImmediateOperand::Word(_) => {
|
||||
ModRmTarget::Register(Register::by_id(ImmediateOperand::Word(rm.into())))
|
||||
Operand::Byte(_) => ModRmTarget::Register(Register::by_id(Operand::Byte(rm))),
|
||||
Operand::Word(_) => {
|
||||
ModRmTarget::Register(Register::by_id(Operand::Word(rm.into())))
|
||||
}
|
||||
};
|
||||
return (target, reg);
|
||||
@@ -208,9 +206,9 @@ impl Disassembler {
|
||||
/// Match the modrm reg bits to the GPR1 mnemonics.
|
||||
/// GPR always has an imm value as second operand, but is available in both
|
||||
/// Byte and Word length.
|
||||
pub fn modrm_reg_to_mnemonic(reg: u8, target: ModRmTarget, imm: ImmediateOperand) -> Mnemonic {
|
||||
pub fn modrm_reg_to_mnemonic(reg: u8, target: ModRmTarget, imm: Operand) -> Mnemonic {
|
||||
match imm {
|
||||
ImmediateOperand::Byte(b) => match reg {
|
||||
Operand::Byte(b) => match reg {
|
||||
0b000 => Mnemonic::ADD_Ib(target, b),
|
||||
0b001 => Mnemonic::OR_Ib(target, b),
|
||||
0b010 => Mnemonic::ADC_Ib(target, b),
|
||||
@@ -221,7 +219,7 @@ impl Disassembler {
|
||||
0b111 => Mnemonic::CMP_Ib(target, b),
|
||||
_ => panic!("Illegal GPR1 mnemonic"),
|
||||
},
|
||||
ImmediateOperand::Word(w) => match reg {
|
||||
Operand::Word(w) => match reg {
|
||||
0b000 => Mnemonic::ADD_Iv(target, w),
|
||||
0b001 => Mnemonic::OR_Iv(target, w),
|
||||
0b010 => Mnemonic::ADC_Iv(target, w),
|
||||
@@ -410,7 +408,7 @@ impl Disassembler {
|
||||
0x8D => modrmv!(self, LEA),
|
||||
|
||||
0x8F => {
|
||||
let target = self.parse_modrm_byte(ImmediateOperand::Word(0)).0;
|
||||
let target = self.parse_modrm_byte(Operand::Word(0)).0;
|
||||
let mem = match target {
|
||||
ModRmTarget::Memory(idx) => idx,
|
||||
_ => panic!("POP_M instruction given a register to pop into"),
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
/// Generate a Mnemonic for an 8-bit Register from a ModRM byte.
|
||||
macro_rules! modrmb {
|
||||
($self:ident, $variant:ident) => {{
|
||||
let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Byte(0));
|
||||
Mnemonic::$variant(target, Register::by_id(ImmediateOperand::Byte(reg)))
|
||||
let (target, reg) = $self.parse_modrm_byte(Operand::Byte(0));
|
||||
Mnemonic::$variant(target, Register::by_id(Operand::Byte(reg)))
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ macro_rules! modrmb {
|
||||
/// Generate a Mnemonic for a 16-bit Register from a ModRM byte.
|
||||
macro_rules! modrmv {
|
||||
($self:ident, $variant:ident) => {{
|
||||
let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Word(0));
|
||||
Mnemonic::$variant(target, Register::by_id(ImmediateOperand::Word(reg.into())))
|
||||
let (target, reg) = $self.parse_modrm_byte(Operand::Word(0));
|
||||
Mnemonic::$variant(target, Register::by_id(Operand::Word(reg.into())))
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ macro_rules! modrmv {
|
||||
/// Generate a Mnemonic for a 16-bit Segment Register from a ModRM byte.
|
||||
macro_rules! modrms {
|
||||
($self:ident, $variant:ident) => {{
|
||||
let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Word(0));
|
||||
let (target, reg) = $self.parse_modrm_byte(Operand::Word(0));
|
||||
Mnemonic::$variant(target, SegmentRegister::by_id(reg))
|
||||
}};
|
||||
}
|
||||
@@ -31,9 +31,9 @@ macro_rules! modrms {
|
||||
/// GPR always has an imm value as second operand.
|
||||
macro_rules! modrmgprb {
|
||||
($self:ident) => {{
|
||||
let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Byte(0));
|
||||
let (target, reg) = $self.parse_modrm_byte(Operand::Byte(0));
|
||||
let imm = $self.parse_byte();
|
||||
Self::modrm_reg_to_mnemonic(reg, target, ImmediateOperand::Byte(imm))
|
||||
Self::modrm_reg_to_mnemonic(reg, target, Operand::Byte(imm))
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ macro_rules! modrmgprb {
|
||||
/// GPR always has an imm value as second operand.
|
||||
macro_rules! modrmgprv {
|
||||
($self:ident) => {{
|
||||
let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Word(0));
|
||||
let (target, reg) = $self.parse_modrm_byte(Operand::Word(0));
|
||||
let imm = $self.parse_word();
|
||||
Self::modrm_reg_to_mnemonic(reg, target, ImmediateOperand::Word(imm))
|
||||
Self::modrm_reg_to_mnemonic(reg, target, Operand::Word(imm))
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@ use core::fmt;
|
||||
|
||||
use crate::register::{Register, SegmentRegister};
|
||||
|
||||
pub type ImmediateByte = u8;
|
||||
pub type ImmediateWord = u16;
|
||||
pub type Byte = u8; // b
|
||||
pub type Word = u16; // w or v
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
/// Encodes either Byte- or Word-sized operands.
|
||||
pub enum ImmediateOperand {
|
||||
Byte(ImmediateByte),
|
||||
Word(ImmediateWord),
|
||||
pub enum Operand {
|
||||
Byte(Byte),
|
||||
Word(Word),
|
||||
}
|
||||
|
||||
impl fmt::Display for ImmediateOperand {
|
||||
impl fmt::Display for Operand {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Byte(byte) => write!(f, "{}", byte),
|
||||
@@ -70,10 +70,10 @@ 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, ImmediateByte), // From Immediate into either Memory or Register
|
||||
ADD_Iv(ModRmTarget, ImmediateWord), // From Immediate into either Memory or Register
|
||||
ADD_ALIb(ImmediateByte),
|
||||
ADD_AXIv(ImmediateWord),
|
||||
ADD_Ib(ModRmTarget, Byte), // From Immediate into either Memory or Register
|
||||
ADD_Iv(ModRmTarget, Word), // From Immediate into either Memory or Register
|
||||
ADD_ALIb(Byte),
|
||||
ADD_AXIv(Word),
|
||||
// PUSH
|
||||
PUSH_R(Register),
|
||||
PUSH_S(SegmentRegister),
|
||||
@@ -84,31 +84,31 @@ pub enum Mnemonic {
|
||||
// OR
|
||||
OR_FromReg(ModRmTarget, Register),
|
||||
OR_ToReg(ModRmTarget, Register),
|
||||
OR_Ib(ModRmTarget, ImmediateByte),
|
||||
OR_Iv(ModRmTarget, ImmediateWord),
|
||||
OR_ALIb(ImmediateByte),
|
||||
OR_AXIv(ImmediateWord),
|
||||
OR_Ib(ModRmTarget, Byte),
|
||||
OR_Iv(ModRmTarget, Word),
|
||||
OR_ALIb(Byte),
|
||||
OR_AXIv(Word),
|
||||
// ADC
|
||||
ADC_FromReg(ModRmTarget, Register),
|
||||
ADC_ToReg(ModRmTarget, Register),
|
||||
ADC_Ib(ModRmTarget, ImmediateByte),
|
||||
ADC_Iv(ModRmTarget, ImmediateWord),
|
||||
ADC_ALIb(ImmediateByte),
|
||||
ADC_AXIv(ImmediateWord),
|
||||
ADC_Ib(ModRmTarget, Byte),
|
||||
ADC_Iv(ModRmTarget, Word),
|
||||
ADC_ALIb(Byte),
|
||||
ADC_AXIv(Word),
|
||||
// SBB
|
||||
SBB_FromReg(ModRmTarget, Register),
|
||||
SBB_ToReg(ModRmTarget, Register),
|
||||
SBB_Ib(ModRmTarget, ImmediateByte),
|
||||
SBB_Iv(ModRmTarget, ImmediateWord),
|
||||
SBB_ALIb(ImmediateByte),
|
||||
SBB_AXIv(ImmediateWord),
|
||||
SBB_Ib(ModRmTarget, Byte),
|
||||
SBB_Iv(ModRmTarget, Word),
|
||||
SBB_ALIb(Byte),
|
||||
SBB_AXIv(Word),
|
||||
// AND
|
||||
AND_FromReg(ModRmTarget, Register),
|
||||
AND_ToReg(ModRmTarget, Register),
|
||||
AND_Ib(ModRmTarget, ImmediateByte),
|
||||
AND_Iv(ModRmTarget, ImmediateWord),
|
||||
AND_ALIb(ImmediateByte),
|
||||
AND_AXIv(ImmediateWord),
|
||||
AND_Ib(ModRmTarget, Byte),
|
||||
AND_Iv(ModRmTarget, Word),
|
||||
AND_ALIb(Byte),
|
||||
AND_AXIv(Word),
|
||||
// Override
|
||||
OVERRIDE(SegmentRegister),
|
||||
// Decimal Adjustment
|
||||
@@ -119,45 +119,45 @@ pub enum Mnemonic {
|
||||
// SUB
|
||||
SUB_FromReg(ModRmTarget, Register),
|
||||
SUB_ToReg(ModRmTarget, Register),
|
||||
SUB_Ib(ModRmTarget, ImmediateByte),
|
||||
SUB_Iv(ModRmTarget, ImmediateWord),
|
||||
SUB_ALIb(ImmediateByte),
|
||||
SUB_AXIv(ImmediateWord),
|
||||
SUB_Ib(ModRmTarget, Byte),
|
||||
SUB_Iv(ModRmTarget, Word),
|
||||
SUB_ALIb(Byte),
|
||||
SUB_AXIv(Word),
|
||||
// XOR
|
||||
XOR_FromReg(ModRmTarget, Register),
|
||||
XOR_ToReg(ModRmTarget, Register),
|
||||
XOR_Ib(ModRmTarget, ImmediateByte),
|
||||
XOR_Iv(ModRmTarget, ImmediateWord),
|
||||
XOR_ALIb(ImmediateByte),
|
||||
XOR_AXIv(ImmediateWord),
|
||||
XOR_Ib(ModRmTarget, Byte),
|
||||
XOR_Iv(ModRmTarget, Word),
|
||||
XOR_ALIb(Byte),
|
||||
XOR_AXIv(Word),
|
||||
// CMP
|
||||
CMP_FromReg(ModRmTarget, Register),
|
||||
CMP_ToReg(ModRmTarget, Register),
|
||||
CMP_Ib(ModRmTarget, ImmediateByte),
|
||||
CMP_Iv(ModRmTarget, ImmediateWord),
|
||||
CMP_ALIb(ImmediateByte),
|
||||
CMP_AXIv(ImmediateWord),
|
||||
CMP_Ib(ModRmTarget, Byte),
|
||||
CMP_Iv(ModRmTarget, Word),
|
||||
CMP_ALIb(Byte),
|
||||
CMP_AXIv(Word),
|
||||
// INC
|
||||
INC(Register),
|
||||
// DEC
|
||||
DEC(Register),
|
||||
// Jumps
|
||||
JO(ImmediateByte),
|
||||
JNO(ImmediateByte),
|
||||
JB(ImmediateByte),
|
||||
JNB(ImmediateByte),
|
||||
JZ(ImmediateByte),
|
||||
JNZ(ImmediateByte),
|
||||
JBE(ImmediateByte),
|
||||
JA(ImmediateByte),
|
||||
JS(ImmediateByte),
|
||||
JNS(ImmediateByte),
|
||||
JPE(ImmediateByte),
|
||||
JPO(ImmediateByte),
|
||||
JL(ImmediateByte),
|
||||
JGE(ImmediateByte),
|
||||
JLE(ImmediateByte),
|
||||
JG(ImmediateByte),
|
||||
JO(Byte),
|
||||
JNO(Byte),
|
||||
JB(Byte),
|
||||
JNB(Byte),
|
||||
JZ(Byte),
|
||||
JNZ(Byte),
|
||||
JBE(Byte),
|
||||
JA(Byte),
|
||||
JS(Byte),
|
||||
JNS(Byte),
|
||||
JPE(Byte),
|
||||
JPO(Byte),
|
||||
JL(Byte),
|
||||
JGE(Byte),
|
||||
JLE(Byte),
|
||||
JG(Byte),
|
||||
// TEST
|
||||
TEST(ModRmTarget, Register),
|
||||
//XHCG
|
||||
@@ -168,7 +168,7 @@ pub enum Mnemonic {
|
||||
MOV_ToReg(ModRmTarget, Register),
|
||||
MOV_FromSReg(ModRmTarget, SegmentRegister),
|
||||
MOV_ToSReg(ModRmTarget, SegmentRegister),
|
||||
MOV_BXIv(ImmediateWord),
|
||||
MOV_BXIv(Word),
|
||||
// LEA
|
||||
LEA(ModRmTarget, Register),
|
||||
// Sign extensions
|
||||
@@ -184,7 +184,7 @@ pub enum Mnemonic {
|
||||
SAHF,
|
||||
LAHF,
|
||||
// INT
|
||||
INT(ImmediateByte),
|
||||
INT(Byte),
|
||||
}
|
||||
|
||||
impl fmt::Display for Mnemonic {
|
||||
@@ -225,7 +225,7 @@ impl std::fmt::Display for ModRmTarget {
|
||||
pub struct MemoryIndex {
|
||||
pub base: Option<Register>,
|
||||
pub index: Option<Register>,
|
||||
pub displacement: Option<ImmediateOperand>,
|
||||
pub displacement: Option<Operand>,
|
||||
}
|
||||
|
||||
impl fmt::Display for MemoryIndex {
|
||||
@@ -255,8 +255,8 @@ impl fmt::Display for MemoryIndex {
|
||||
#[derive(Debug, Clone)]
|
||||
/// 32-bit segment:offset pointer (e.g. for CALL instruction)
|
||||
pub struct Pointer {
|
||||
pub segment: ImmediateWord,
|
||||
pub offset: ImmediateWord,
|
||||
pub segment: Word,
|
||||
pub offset: Word,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Pointer {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use core::fmt;
|
||||
|
||||
use crate::instructions::ImmediateOperand;
|
||||
use crate::instructions::Operand;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
@@ -35,9 +35,9 @@ pub type RegisterId = u8;
|
||||
#[allow(dead_code)]
|
||||
impl Register {
|
||||
/// Find the register corresponding to the 8086 bytecode ID
|
||||
pub fn by_id(id: ImmediateOperand) -> Self {
|
||||
pub fn by_id(id: Operand) -> Self {
|
||||
match id {
|
||||
ImmediateOperand::Byte(b) => match b {
|
||||
Operand::Byte(b) => match b {
|
||||
0b000 => Self::AL,
|
||||
0b001 => Self::CL,
|
||||
0b010 => Self::DL,
|
||||
@@ -48,7 +48,7 @@ impl Register {
|
||||
0b111 => Self::BH,
|
||||
_ => panic!("Invalid 8bit register ID encountered"),
|
||||
},
|
||||
ImmediateOperand::Word(w) => match w {
|
||||
Operand::Word(w) => match w {
|
||||
0b000 => Self::AX,
|
||||
0b001 => Self::CX,
|
||||
0b010 => Self::DX,
|
||||
|
||||
Reference in New Issue
Block a user