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 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"),

View File

@@ -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))
}};
}

View File

@@ -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 {

View File

@@ -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,