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:
2025-05-14 10:40:52 +09:00
parent a61b82fe22
commit b5c178ea61
4 changed files with 84 additions and 86 deletions

View File

@@ -2,7 +2,7 @@ use core::fmt;
use std::{fs::File, io::Read, process::exit}; use std::{fs::File, io::Read, process::exit};
use crate::aout::Aout; 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::register::{Register, RegisterId, SegmentRegister};
use crate::{ use crate::{
Args, Args,
@@ -108,7 +108,7 @@ impl Disassembler {
/// Parse a single modrm byte, return the resulting MemoryIndex and advance the offset. /// Parse a single modrm byte, return the resulting MemoryIndex and advance the offset.
/// Returns the parsed modrm target and the source register /// 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 // advance to operand
self.offset += 1; self.offset += 1;
let modrm = self.text[self.offset]; let modrm = self.text[self.offset];
@@ -129,28 +129,26 @@ impl Disassembler {
0b00 => { 0b00 => {
if rm == 0b110 { if rm == 0b110 {
log::debug!("Additional word during ModRM parsing was read with mod 0."); 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 { } else {
displacement = None; displacement = None;
} }
} }
0b01 => { 0b01 => {
log::debug!("Additional byte during ModRM parsing was read."); log::debug!("Additional byte during ModRM parsing was read.");
displacement = Some(ImmediateOperand::Byte(self.parse_byte())) displacement = Some(Operand::Byte(self.parse_byte()))
} }
0b10 => { 0b10 => {
log::debug!("Additional word during ModRM parsing was read."); log::debug!("Additional word during ModRM parsing was read.");
displacement = Some(ImmediateOperand::Word(self.parse_word())); displacement = Some(Operand::Word(self.parse_word()));
} }
0b11 => { 0b11 => {
log::debug!("ModRM (0b{:b}) to/from Register (0b{:b})", rm, reg); 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) // XXX: find a nicer way instead of using Byte(0) and Word(0)
let target = match width { let target = match width {
ImmediateOperand::Byte(_) => { Operand::Byte(_) => ModRmTarget::Register(Register::by_id(Operand::Byte(rm))),
ModRmTarget::Register(Register::by_id(ImmediateOperand::Byte(rm))) Operand::Word(_) => {
} ModRmTarget::Register(Register::by_id(Operand::Word(rm.into())))
ImmediateOperand::Word(_) => {
ModRmTarget::Register(Register::by_id(ImmediateOperand::Word(rm.into())))
} }
}; };
return (target, reg); return (target, reg);
@@ -208,9 +206,9 @@ impl Disassembler {
/// Match the modrm reg bits to the GPR1 mnemonics. /// Match the modrm reg bits to the GPR1 mnemonics.
/// GPR always has an imm value as second operand, but is available in both /// GPR always has an imm value as second operand, but is available in both
/// Byte and Word length. /// 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 { match imm {
ImmediateOperand::Byte(b) => match reg { Operand::Byte(b) => match reg {
0b000 => Mnemonic::ADD_Ib(target, b), 0b000 => Mnemonic::ADD_Ib(target, b),
0b001 => Mnemonic::OR_Ib(target, b), 0b001 => Mnemonic::OR_Ib(target, b),
0b010 => Mnemonic::ADC_Ib(target, b), 0b010 => Mnemonic::ADC_Ib(target, b),
@@ -221,7 +219,7 @@ impl Disassembler {
0b111 => Mnemonic::CMP_Ib(target, b), 0b111 => Mnemonic::CMP_Ib(target, b),
_ => panic!("Illegal GPR1 mnemonic"), _ => panic!("Illegal GPR1 mnemonic"),
}, },
ImmediateOperand::Word(w) => match reg { Operand::Word(w) => match reg {
0b000 => Mnemonic::ADD_Iv(target, w), 0b000 => Mnemonic::ADD_Iv(target, w),
0b001 => Mnemonic::OR_Iv(target, w), 0b001 => Mnemonic::OR_Iv(target, w),
0b010 => Mnemonic::ADC_Iv(target, w), 0b010 => Mnemonic::ADC_Iv(target, w),
@@ -410,7 +408,7 @@ impl Disassembler {
0x8D => modrmv!(self, LEA), 0x8D => modrmv!(self, LEA),
0x8F => { 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 { let mem = match target {
ModRmTarget::Memory(idx) => idx, ModRmTarget::Memory(idx) => idx,
_ => panic!("POP_M instruction given a register to pop into"), _ => panic!("POP_M instruction given a register to pop into"),

View File

@@ -2,8 +2,8 @@
/// Generate a Mnemonic for an 8-bit Register from a ModRM byte. /// Generate a Mnemonic for an 8-bit Register from a ModRM byte.
macro_rules! modrmb { macro_rules! modrmb {
($self:ident, $variant:ident) => {{ ($self:ident, $variant:ident) => {{
let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Byte(0)); let (target, reg) = $self.parse_modrm_byte(Operand::Byte(0));
Mnemonic::$variant(target, Register::by_id(ImmediateOperand::Byte(reg))) 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. /// Generate a Mnemonic for a 16-bit Register from a ModRM byte.
macro_rules! modrmv { macro_rules! modrmv {
($self:ident, $variant:ident) => {{ ($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, Register::by_id(ImmediateOperand::Word(reg.into()))) 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. /// Generate a Mnemonic for a 16-bit Segment Register from a ModRM byte.
macro_rules! modrms { macro_rules! modrms {
($self:ident, $variant:ident) => {{ ($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)) Mnemonic::$variant(target, SegmentRegister::by_id(reg))
}}; }};
} }
@@ -31,9 +31,9 @@ macro_rules! modrms {
/// GPR always has an imm value as second operand. /// GPR always has an imm value as second operand.
macro_rules! modrmgprb { macro_rules! modrmgprb {
($self:ident) => {{ ($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(); 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. /// GPR always has an imm value as second operand.
macro_rules! modrmgprv { macro_rules! modrmgprv {
($self:ident) => {{ ($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(); 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))
}}; }};
} }

View File

@@ -2,18 +2,18 @@ use core::fmt;
use crate::register::{Register, SegmentRegister}; use crate::register::{Register, SegmentRegister};
pub type ImmediateByte = u8; pub type Byte = u8; // b
pub type ImmediateWord = u16; pub type Word = u16; // w or v
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(dead_code)] #[allow(dead_code)]
/// Encodes either Byte- or Word-sized operands. /// Encodes either Byte- or Word-sized operands.
pub enum ImmediateOperand { pub enum Operand {
Byte(ImmediateByte), Byte(Byte),
Word(ImmediateWord), Word(Word),
} }
impl fmt::Display for ImmediateOperand { impl fmt::Display for Operand {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
Self::Byte(byte) => write!(f, "{}", byte), Self::Byte(byte) => write!(f, "{}", byte),
@@ -70,10 +70,10 @@ pub enum Mnemonic {
// ADD // ADD
ADD_FromReg(ModRmTarget, Register), // From Register into either Memory or Register ADD_FromReg(ModRmTarget, Register), // From Register into either Memory or Register
ADD_ToReg(ModRmTarget, Register), // From either Memory or Register into Reigster ADD_ToReg(ModRmTarget, Register), // From either Memory or Register into Reigster
ADD_Ib(ModRmTarget, ImmediateByte), // From Immediate into either Memory or Register ADD_Ib(ModRmTarget, Byte), // From Immediate into either Memory or Register
ADD_Iv(ModRmTarget, ImmediateWord), // From Immediate into either Memory or Register ADD_Iv(ModRmTarget, Word), // From Immediate into either Memory or Register
ADD_ALIb(ImmediateByte), ADD_ALIb(Byte),
ADD_AXIv(ImmediateWord), ADD_AXIv(Word),
// PUSH // PUSH
PUSH_R(Register), PUSH_R(Register),
PUSH_S(SegmentRegister), PUSH_S(SegmentRegister),
@@ -84,31 +84,31 @@ pub enum Mnemonic {
// OR // OR
OR_FromReg(ModRmTarget, Register), OR_FromReg(ModRmTarget, Register),
OR_ToReg(ModRmTarget, Register), OR_ToReg(ModRmTarget, Register),
OR_Ib(ModRmTarget, ImmediateByte), OR_Ib(ModRmTarget, Byte),
OR_Iv(ModRmTarget, ImmediateWord), OR_Iv(ModRmTarget, Word),
OR_ALIb(ImmediateByte), OR_ALIb(Byte),
OR_AXIv(ImmediateWord), OR_AXIv(Word),
// ADC // ADC
ADC_FromReg(ModRmTarget, Register), ADC_FromReg(ModRmTarget, Register),
ADC_ToReg(ModRmTarget, Register), ADC_ToReg(ModRmTarget, Register),
ADC_Ib(ModRmTarget, ImmediateByte), ADC_Ib(ModRmTarget, Byte),
ADC_Iv(ModRmTarget, ImmediateWord), ADC_Iv(ModRmTarget, Word),
ADC_ALIb(ImmediateByte), ADC_ALIb(Byte),
ADC_AXIv(ImmediateWord), ADC_AXIv(Word),
// SBB // SBB
SBB_FromReg(ModRmTarget, Register), SBB_FromReg(ModRmTarget, Register),
SBB_ToReg(ModRmTarget, Register), SBB_ToReg(ModRmTarget, Register),
SBB_Ib(ModRmTarget, ImmediateByte), SBB_Ib(ModRmTarget, Byte),
SBB_Iv(ModRmTarget, ImmediateWord), SBB_Iv(ModRmTarget, Word),
SBB_ALIb(ImmediateByte), SBB_ALIb(Byte),
SBB_AXIv(ImmediateWord), SBB_AXIv(Word),
// AND // AND
AND_FromReg(ModRmTarget, Register), AND_FromReg(ModRmTarget, Register),
AND_ToReg(ModRmTarget, Register), AND_ToReg(ModRmTarget, Register),
AND_Ib(ModRmTarget, ImmediateByte), AND_Ib(ModRmTarget, Byte),
AND_Iv(ModRmTarget, ImmediateWord), AND_Iv(ModRmTarget, Word),
AND_ALIb(ImmediateByte), AND_ALIb(Byte),
AND_AXIv(ImmediateWord), AND_AXIv(Word),
// Override // Override
OVERRIDE(SegmentRegister), OVERRIDE(SegmentRegister),
// Decimal Adjustment // Decimal Adjustment
@@ -119,45 +119,45 @@ pub enum Mnemonic {
// SUB // SUB
SUB_FromReg(ModRmTarget, Register), SUB_FromReg(ModRmTarget, Register),
SUB_ToReg(ModRmTarget, Register), SUB_ToReg(ModRmTarget, Register),
SUB_Ib(ModRmTarget, ImmediateByte), SUB_Ib(ModRmTarget, Byte),
SUB_Iv(ModRmTarget, ImmediateWord), SUB_Iv(ModRmTarget, Word),
SUB_ALIb(ImmediateByte), SUB_ALIb(Byte),
SUB_AXIv(ImmediateWord), SUB_AXIv(Word),
// XOR // XOR
XOR_FromReg(ModRmTarget, Register), XOR_FromReg(ModRmTarget, Register),
XOR_ToReg(ModRmTarget, Register), XOR_ToReg(ModRmTarget, Register),
XOR_Ib(ModRmTarget, ImmediateByte), XOR_Ib(ModRmTarget, Byte),
XOR_Iv(ModRmTarget, ImmediateWord), XOR_Iv(ModRmTarget, Word),
XOR_ALIb(ImmediateByte), XOR_ALIb(Byte),
XOR_AXIv(ImmediateWord), XOR_AXIv(Word),
// CMP // CMP
CMP_FromReg(ModRmTarget, Register), CMP_FromReg(ModRmTarget, Register),
CMP_ToReg(ModRmTarget, Register), CMP_ToReg(ModRmTarget, Register),
CMP_Ib(ModRmTarget, ImmediateByte), CMP_Ib(ModRmTarget, Byte),
CMP_Iv(ModRmTarget, ImmediateWord), CMP_Iv(ModRmTarget, Word),
CMP_ALIb(ImmediateByte), CMP_ALIb(Byte),
CMP_AXIv(ImmediateWord), CMP_AXIv(Word),
// INC // INC
INC(Register), INC(Register),
// DEC // DEC
DEC(Register), DEC(Register),
// Jumps // Jumps
JO(ImmediateByte), JO(Byte),
JNO(ImmediateByte), JNO(Byte),
JB(ImmediateByte), JB(Byte),
JNB(ImmediateByte), JNB(Byte),
JZ(ImmediateByte), JZ(Byte),
JNZ(ImmediateByte), JNZ(Byte),
JBE(ImmediateByte), JBE(Byte),
JA(ImmediateByte), JA(Byte),
JS(ImmediateByte), JS(Byte),
JNS(ImmediateByte), JNS(Byte),
JPE(ImmediateByte), JPE(Byte),
JPO(ImmediateByte), JPO(Byte),
JL(ImmediateByte), JL(Byte),
JGE(ImmediateByte), JGE(Byte),
JLE(ImmediateByte), JLE(Byte),
JG(ImmediateByte), JG(Byte),
// TEST // TEST
TEST(ModRmTarget, Register), TEST(ModRmTarget, Register),
//XHCG //XHCG
@@ -168,7 +168,7 @@ pub enum Mnemonic {
MOV_ToReg(ModRmTarget, Register), MOV_ToReg(ModRmTarget, Register),
MOV_FromSReg(ModRmTarget, SegmentRegister), MOV_FromSReg(ModRmTarget, SegmentRegister),
MOV_ToSReg(ModRmTarget, SegmentRegister), MOV_ToSReg(ModRmTarget, SegmentRegister),
MOV_BXIv(ImmediateWord), MOV_BXIv(Word),
// LEA // LEA
LEA(ModRmTarget, Register), LEA(ModRmTarget, Register),
// Sign extensions // Sign extensions
@@ -184,7 +184,7 @@ pub enum Mnemonic {
SAHF, SAHF,
LAHF, LAHF,
// INT // INT
INT(ImmediateByte), INT(Byte),
} }
impl fmt::Display for Mnemonic { impl fmt::Display for Mnemonic {
@@ -225,7 +225,7 @@ impl std::fmt::Display for ModRmTarget {
pub struct MemoryIndex { pub struct MemoryIndex {
pub base: Option<Register>, pub base: Option<Register>,
pub index: Option<Register>, pub index: Option<Register>,
pub displacement: Option<ImmediateOperand>, pub displacement: Option<Operand>,
} }
impl fmt::Display for MemoryIndex { impl fmt::Display for MemoryIndex {
@@ -255,8 +255,8 @@ impl fmt::Display for MemoryIndex {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
/// 32-bit segment:offset pointer (e.g. for CALL instruction) /// 32-bit segment:offset pointer (e.g. for CALL instruction)
pub struct Pointer { pub struct Pointer {
pub segment: ImmediateWord, pub segment: Word,
pub offset: ImmediateWord, pub offset: Word,
} }
impl std::fmt::Display for Pointer { impl std::fmt::Display for Pointer {

View File

@@ -1,6 +1,6 @@
use core::fmt; use core::fmt;
use crate::instructions::ImmediateOperand; use crate::instructions::Operand;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(dead_code)] #[allow(dead_code)]
@@ -35,9 +35,9 @@ pub type RegisterId = u8;
#[allow(dead_code)] #[allow(dead_code)]
impl Register { impl Register {
/// Find the register corresponding to the 8086 bytecode ID /// 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 { match id {
ImmediateOperand::Byte(b) => match b { Operand::Byte(b) => match b {
0b000 => Self::AL, 0b000 => Self::AL,
0b001 => Self::CL, 0b001 => Self::CL,
0b010 => Self::DL, 0b010 => Self::DL,
@@ -48,7 +48,7 @@ impl Register {
0b111 => Self::BH, 0b111 => Self::BH,
_ => panic!("Invalid 8bit register ID encountered"), _ => panic!("Invalid 8bit register ID encountered"),
}, },
ImmediateOperand::Word(w) => match w { Operand::Word(w) => match w {
0b000 => Self::AX, 0b000 => Self::AX,
0b001 => Self::CX, 0b001 => Self::CX,
0b010 => Self::DX, 0b010 => Self::DX,