From 232b73aad8ba382b84910dd783f1ef0840c314c8 Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Thu, 5 Jun 2025 10:07:57 +0900 Subject: [PATCH] chore: Rename Operand -> ImmediateOperand --- src/disasm.rs | 74 +++++++++++++++++----------------- src/disasm_macros.rs | 10 ++--- src/interpreter/computer.rs | 27 ++++++------- src/interpreter/interpreter.rs | 16 ++++---- src/interpreter/memory.rs | 41 +++++++++++-------- src/interpreter/register.rs | 46 ++++++++++----------- src/operands.rs | 49 ++++++++++++---------- src/register.rs | 8 ++-- 8 files changed, 141 insertions(+), 130 deletions(-) diff --git a/src/disasm.rs b/src/disasm.rs index 6ab1447..6606ca5 100644 --- a/src/disasm.rs +++ b/src/disasm.rs @@ -2,7 +2,7 @@ use crate::aout::Aout; use crate::operands::{ - Byte, DWord, Displacement, IByte, IWord, MemoryIndex, ModRmTarget, Operand, Pointer16, + Byte, DWord, Displacement, IByte, IWord, ImmediateOperand, MemoryIndex, ModRmTarget, Pointer16, Pointer32, Word, }; use crate::register::{Register, RegisterId, SegmentRegister}; @@ -238,7 +238,7 @@ impl Disassembler { /// or even mnemonic in the group-type instructions. fn parse_modrm_byte( &mut self, - register_width: Operand, + register_width: ImmediateOperand, ) -> Result<(ModRmTarget, RegisterId), DisasmError> { let modrm = self.parse_byte()?; @@ -291,9 +291,11 @@ impl Disassembler { "ModRM selected Register to Register: ({rm:#b}) to/from RegID ({reg:#b})" ); let target = match register_width { - Operand::Byte(_) => ModRmTarget::Register(Register::by_id(Operand::Byte(rm))?), - Operand::Word(_) => { - ModRmTarget::Register(Register::by_id(Operand::Word(rm as Word))?) + ImmediateOperand::Byte(_) => { + ModRmTarget::Register(Register::by_id(ImmediateOperand::Byte(rm))?) + } + ImmediateOperand::Word(_) => { + ModRmTarget::Register(Register::by_id(ImmediateOperand::Word(rm as Word))?) } }; return Ok((target, reg)); @@ -355,10 +357,10 @@ impl Disassembler { fn modrm_reg_to_grp1( reg: u8, target: ModRmTarget, - instruction_width: Operand, + instruction_width: ImmediateOperand, ) -> Result { match instruction_width { - Operand::Byte(b) => match reg { + ImmediateOperand::Byte(b) => match reg { 0b000 => Ok(Mnemonic::ADD_Ib(target, b)), 0b001 => Ok(Mnemonic::OR_Ib(target, b)), 0b010 => Ok(Mnemonic::ADC_Ib(target, b)), @@ -369,7 +371,7 @@ impl Disassembler { 0b111 => Ok(Mnemonic::CMP_Ib(target, b)), _ => return Err(DisasmError::IllegalGroupMnemonic(1, reg)), }, - Operand::Word(w) => match reg { + ImmediateOperand::Word(w) => match reg { 0b000 => Ok(Mnemonic::ADD_Iv(target, w)), 0b001 => Ok(Mnemonic::OR_Iv(target, w)), 0b010 => Ok(Mnemonic::ADC_Iv(target, w)), @@ -428,12 +430,12 @@ impl Disassembler { &mut self, reg: u8, target: ModRmTarget, - width: Operand, + width: ImmediateOperand, ) -> Result { match reg { 0b000 => match width { - Operand::Byte(_) => Ok(Mnemonic::TEST_Ib(target, self.parse_byte()?)), - Operand::Word(_) => Ok(Mnemonic::TEST_Iv(target, self.parse_word()?)), + ImmediateOperand::Byte(_) => Ok(Mnemonic::TEST_Ib(target, self.parse_byte()?)), + ImmediateOperand::Word(_) => Ok(Mnemonic::TEST_Iv(target, self.parse_word()?)), }, // 0b001 => // unused 0b010 => Ok(Mnemonic::NOT(target)), @@ -635,26 +637,26 @@ impl Disassembler { // Group 1 0x80 => { - let (target, reg) = self.parse_modrm_byte(Operand::Byte(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Byte(0))?; let imm = self.parse_byte()?; - Self::modrm_reg_to_grp1(reg, target, Operand::Byte(imm))? + Self::modrm_reg_to_grp1(reg, target, ImmediateOperand::Byte(imm))? } 0x81 => { - let (target, reg) = self.parse_modrm_byte(Operand::Word(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; let imm = self.parse_word()?; - Self::modrm_reg_to_grp1(reg, target, Operand::Word(imm))? + Self::modrm_reg_to_grp1(reg, target, ImmediateOperand::Word(imm))? } 0x82 => { // same as 0x80 - let (target, reg) = self.parse_modrm_byte(Operand::Byte(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Byte(0))?; let imm = self.parse_byte()?; - Self::modrm_reg_to_grp1(reg, target, Operand::Byte(imm))? + Self::modrm_reg_to_grp1(reg, target, ImmediateOperand::Byte(imm))? } 0x83 => { // byte extended version - let (target, reg) = self.parse_modrm_byte(Operand::Word(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; let imm = self.parse_byte()?; - Self::modrm_reg_to_grp1(reg, target, Operand::Byte(imm))? + Self::modrm_reg_to_grp1(reg, target, ImmediateOperand::Byte(imm))? } 0x84 => modrm_8b_register!(self, TEST), @@ -673,7 +675,7 @@ impl Disassembler { 0x8D => modrm_16b_register!(self, LEA), 0x8F => { - let (target, _) = self.parse_modrm_byte(Operand::Word(0))?; + let (target, _) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; let mem = match target { ModRmTarget::Memory(idx) => idx, _ => { @@ -749,24 +751,24 @@ impl Disassembler { 0xC3 => Mnemonic::RET, 0xC4 => { - let (target, reg_id) = self.parse_modrm_byte(Operand::Word(0))?; - let reg = Register::by_id(Operand::Word(reg_id as Word))?; + let (target, reg_id) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; + let reg = Register::by_id(ImmediateOperand::Word(reg_id as Word))?; let ptr = Pointer16::try_from(target)?; Mnemonic::LES(reg, ptr) } 0xC5 => { - let (target, reg_id) = self.parse_modrm_byte(Operand::Word(0))?; - let reg = Register::by_id(Operand::Word(reg_id as Word))?; + let (target, reg_id) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; + let reg = Register::by_id(ImmediateOperand::Word(reg_id as Word))?; let ptr = Pointer16::try_from(target)?; Mnemonic::LDS(reg, ptr) } 0xC6 => { - let (target, _) = self.parse_modrm_byte(Operand::Byte(0))?; + let (target, _) = self.parse_modrm_byte(ImmediateOperand::Byte(0))?; Mnemonic::MOV_Ib(target, self.parse_byte()?) } 0xC7 => { - let (target, _) = self.parse_modrm_byte(Operand::Word(0))?; + let (target, _) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; Mnemonic::MOV_Iv(target, self.parse_word()?) } @@ -783,19 +785,19 @@ impl Disassembler { // Group 2 0xD0 => { - let (target, reg) = self.parse_modrm_byte(Operand::Byte(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Byte(0))?; Self::modrm_reg_to_grp2_1(reg, target)? } 0xD1 => { - let (target, reg) = self.parse_modrm_byte(Operand::Word(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; Self::modrm_reg_to_grp2_1(reg, target)? } 0xD2 => { - let (target, reg) = self.parse_modrm_byte(Operand::Byte(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Byte(0))?; Self::modrm_reg_to_grp2_cl(reg, target)? } 0xD3 => { - let (target, reg) = self.parse_modrm_byte(Operand::Word(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; Self::modrm_reg_to_grp2_cl(reg, target)? } @@ -842,13 +844,13 @@ impl Disassembler { // Group 3a 0xF6 => { - let (target, reg) = self.parse_modrm_byte(Operand::Byte(0))?; - self.modrm_reg_to_grp3(reg, target, Operand::Byte(0))? + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Byte(0))?; + self.modrm_reg_to_grp3(reg, target, ImmediateOperand::Byte(0))? } // Group 3b 0xF7 => { - let (target, reg) = self.parse_modrm_byte(Operand::Word(0))?; - self.modrm_reg_to_grp3(reg, target, Operand::Word(0))? + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; + self.modrm_reg_to_grp3(reg, target, ImmediateOperand::Word(0))? } 0xF8 => Mnemonic::CLC, @@ -860,7 +862,7 @@ impl Disassembler { // Group 4 0xFE => { - let (target, reg) = self.parse_modrm_byte(Operand::Byte(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Byte(0))?; match reg { 0b0 => Mnemonic::INC_Mod(target), 0b1 => Mnemonic::DEC_Mod(target), @@ -870,7 +872,7 @@ impl Disassembler { // Group 5 0xFF => { - let (target, reg) = self.parse_modrm_byte(Operand::Word(0))?; + let (target, reg) = self.parse_modrm_byte(ImmediateOperand::Word(0))?; match reg { 0b000 => Mnemonic::INC_Mod(target), 0b001 => Mnemonic::DEC_Mod(target), diff --git a/src/disasm_macros.rs b/src/disasm_macros.rs index bdfcdee..c0e1bc2 100644 --- a/src/disasm_macros.rs +++ b/src/disasm_macros.rs @@ -4,8 +4,8 @@ /// Generate a Mnemonic for an 8-bit Register from a ModRM byte. macro_rules! modrm_8b_register { ($self:ident, $variant:ident) => {{ - let (target, reg) = $self.parse_modrm_byte(Operand::Byte(0))?; - Mnemonic::$variant(target, Register::by_id(Operand::Byte(reg))?) + let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Byte(0))?; + Mnemonic::$variant(target, Register::by_id(ImmediateOperand::Byte(reg))?) }}; } @@ -13,8 +13,8 @@ macro_rules! modrm_8b_register { /// Generate a Mnemonic for a 16-bit Register from a ModRM byte. macro_rules! modrm_16b_register { ($self:ident, $variant:ident) => {{ - let (target, reg) = $self.parse_modrm_byte(Operand::Word(0))?; - Mnemonic::$variant(target, Register::by_id(Operand::Word(reg.into()))?) + let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Word(0))?; + Mnemonic::$variant(target, Register::by_id(ImmediateOperand::Word(reg.into()))?) }}; } @@ -22,7 +22,7 @@ macro_rules! modrm_16b_register { /// Generate a Mnemonic for a 16-bit Segment Register from a ModRM byte. macro_rules! modrm_sregister { ($self:ident, $variant:ident) => {{ - let (target, reg) = $self.parse_modrm_byte(Operand::Word(0))?; + let (target, reg) = $self.parse_modrm_byte(ImmediateOperand::Word(0))?; Mnemonic::$variant(target, SegmentRegister::by_id(reg)?) }}; } diff --git a/src/interpreter/computer.rs b/src/interpreter/computer.rs index a04609c..30a6c84 100644 --- a/src/interpreter/computer.rs +++ b/src/interpreter/computer.rs @@ -1,13 +1,13 @@ use core::fmt; -use crate::operands::{ModRmTarget, Operand}; +use crate::operands::{ImmediateOperand, ModRmTarget}; use super::{flags::Flags, memory::Memory, register::Register}; /// Wrapper for easier argument passing of arithmetic operations. #[derive(Debug, Clone)] -pub enum Argument { - Operand(crate::operands::Operand), +pub enum Operand { + Immediate(crate::operands::ImmediateOperand), ModRmTarget(ModRmTarget), } @@ -30,10 +30,10 @@ impl Computer { /// Adds two [`Argument`]s, saves it to `dest` and sets flags, if necessary. /// A value can never be saved to an immediate Operand, so `dest` can only /// be a [`ModRmTarget`]. - pub fn add(&mut self, dest: ModRmTarget, src: Argument) { + pub fn add(&mut self, dest: ModRmTarget, src: Operand) { match src { - Argument::ModRmTarget(src_target) => self.add_modrm(dest, src_target), - Argument::Operand(src_operand) => self.add_imm(dest, src_operand), + Operand::ModRmTarget(src_target) => self.add_modrm(dest, src_target), + Operand::Immediate(src_operand) => self.add_imm(dest, src_operand), } } @@ -45,11 +45,10 @@ impl Computer { ModRmTarget::Memory(_) => panic!("Cannot add Memory to Memory!"), // mem, reg ModRmTarget::Register(src_register) => { - let lhs = self.memory.read_from_memidx(&self.regs, dest_memory_idx); + let lhs = self.memory.read(&self.regs, dest_memory_idx); let rhs = self.regs.read(src_register); let result = lhs + rhs; - self.memory - .write_from_memidx(&self.regs, dest_memory_idx, result); + self.memory.write(&self.regs, dest_memory_idx, result); // unsigned overflow self.flags.of = result < rhs; } @@ -58,7 +57,7 @@ impl Computer { // reg, mem ModRmTarget::Memory(src_memory_index) => { let lhs = self.regs.read(dest_register); - let rhs = self.memory.read_from_memidx(&self.regs, src_memory_index); + let rhs = self.memory.read(&self.regs, src_memory_index); let result = lhs + rhs; self.regs.write(dest_register, result); // unsigned overflow @@ -78,16 +77,16 @@ impl Computer { } } - /// Adds an immediate [`Operand`] to a location pointed to by a + /// Adds an [`ImmediateOperand`] to a location pointed to by a /// [`ModRmTarget`], saves it to dest and sets flags, if necessary. - fn add_imm(&mut self, dest: ModRmTarget, src: Operand) { + fn add_imm(&mut self, dest: ModRmTarget, src: ImmediateOperand) { match dest { ModRmTarget::Memory(dest_mem) => { - let lhs = self.memory.read_from_memidx(&self.regs, dest_mem); + let lhs = self.memory.read(&self.regs, dest_mem); let result = lhs + src; // unsigned overflow self.flags.of = result < src; - self.memory.write_from_memidx(&self.regs, dest_mem, result); + self.memory.write(&self.regs, dest_mem, result); } ModRmTarget::Register(dest_reg) => { let lhs = self.regs.read(dest_reg); diff --git a/src/interpreter/interpreter.rs b/src/interpreter/interpreter.rs index fc941a0..51d0a34 100644 --- a/src/interpreter/interpreter.rs +++ b/src/interpreter/interpreter.rs @@ -3,10 +3,10 @@ use std::{fmt::Debug, process::exit}; use crate::{ instructions::{Instruction, Mnemonic}, - operands::{Byte, ModRmTarget, Operand, Word}, + operands::{Byte, ImmediateOperand, ModRmTarget, Word}, }; -use super::computer::{Argument, Computer}; +use super::computer::{Computer, Operand}; #[derive(Debug, Clone)] pub enum InterpreterError { @@ -56,23 +56,23 @@ impl Interpreter { */ Mnemonic::ADD_FromReg(dest, src) => self .computer - .add(dest, Argument::ModRmTarget(ModRmTarget::Register(src))), + .add(dest, Operand::ModRmTarget(ModRmTarget::Register(src))), Mnemonic::ADD_ToReg(src, dest) => self .computer - .add(ModRmTarget::Register(dest), Argument::ModRmTarget(src)), + .add(ModRmTarget::Register(dest), Operand::ModRmTarget(src)), Mnemonic::ADD_Ib(dest, src) => self .computer - .add(dest, Argument::Operand(Operand::Byte(src))), + .add(dest, Operand::Immediate(ImmediateOperand::Byte(src))), Mnemonic::ADD_Iv(dest, src) => self .computer - .add(dest, Argument::Operand(Operand::Word(src))), + .add(dest, Operand::Immediate(ImmediateOperand::Word(src))), Mnemonic::ADD_ALIb(src_byte) => self.computer.add( ModRmTarget::Register(crate::register::Register::AL), - Argument::Operand(Operand::Byte(src_byte)), + Operand::Immediate(ImmediateOperand::Byte(src_byte)), ), Mnemonic::ADD_AXIv(src_word) => self.computer.add( ModRmTarget::Register(crate::register::Register::AX), - Argument::Operand(Operand::Word(src_word)), + Operand::Immediate(ImmediateOperand::Word(src_word)), ), /* diff --git a/src/interpreter/memory.rs b/src/interpreter/memory.rs index 0b990c6..2578f17 100644 --- a/src/interpreter/memory.rs +++ b/src/interpreter/memory.rs @@ -1,4 +1,4 @@ -use crate::operands::{Byte, Displacement, MemoryIndex, Operand, Word}; +use crate::operands::{Byte, Displacement, ImmediateOperand, MemoryIndex, Word}; #[derive(Debug, Clone, Copy)] pub struct Memory { @@ -10,23 +10,23 @@ impl Memory { Self { memory: [0; 65536] } } - // Write an [`Operand`] to a memory location indexed by a [`MemoryIndex`]. + // Write an [`ImmediateOperand`] to a memory location indexed by a [`MemoryIndex`]. pub fn write( &mut self, regs: &crate::interpreter::register::Register, idx: MemoryIndex, - val: Operand, + val: ImmediateOperand, ) { match Memory::calc_memidx(regs, idx) { - Operand::Byte(idx_byte) => match val { - Operand::Byte(value) => { + ImmediateOperand::Byte(idx_byte) => match val { + ImmediateOperand::Byte(value) => { log::debug!("Writing byte {value:#04x} to memory location {idx_byte:#04x}"); self.memory[idx_byte as usize] = value } - Operand::Word(_) => panic!("Cannot add Word to Byte Memory Index"), + ImmediateOperand::Word(_) => panic!("Cannot add Word to Byte Memory Index"), }, - Operand::Word(idx_word) => match val { - Operand::Word(value) => { + ImmediateOperand::Word(idx_word) => match val { + ImmediateOperand::Word(value) => { let byte1 = idx_word / 2; let byte2 = idx_word / 2 + 1; let [low, high]: [u8; 2] = value.to_le_bytes(); @@ -36,7 +36,7 @@ impl Memory { self.memory[byte1 as usize] = low; self.memory[byte1 as usize] = high; } - Operand::Byte(value) => { + ImmediateOperand::Byte(value) => { self.memory[(idx_word * 2) as usize] = value; } }, @@ -44,17 +44,21 @@ impl Memory { } /// Read into memory with a [`MemoryIndex`] as index. - pub fn read(&self, regs: &crate::interpreter::register::Register, idx: MemoryIndex) -> Operand { + pub fn read( + &self, + regs: &crate::interpreter::register::Register, + idx: MemoryIndex, + ) -> ImmediateOperand { match Memory::calc_memidx(regs, idx) { - Operand::Byte(byte) => { + ImmediateOperand::Byte(byte) => { log::debug!("Reading byte {byte:#04x} from memory"); - Operand::Byte(self.memory[byte as usize]) + ImmediateOperand::Byte(self.memory[byte as usize]) } - Operand::Word(word) => { + ImmediateOperand::Word(word) => { let byte1 = word / 2; let byte2 = word / 2 + 1; log::debug!("Reading bytes {byte1:#04x} and {byte2:#04x} from memory"); - Operand::Word(Word::from_le_bytes([ + ImmediateOperand::Word(Word::from_le_bytes([ self.memory[byte1 as usize], self.memory[byte2 as usize], ])) @@ -63,9 +67,12 @@ impl Memory { } /// Calculate the absolute Memory Index from a [`MemoryIndex`] struct. - fn calc_memidx(regs: &crate::interpreter::register::Register, idx: MemoryIndex) -> Operand { - let mut base = Operand::Word(0); - let mut index = Operand::Word(0); + fn calc_memidx( + regs: &crate::interpreter::register::Register, + idx: MemoryIndex, + ) -> ImmediateOperand { + let mut base = ImmediateOperand::Word(0); + let mut index = ImmediateOperand::Word(0); let mut disp = Displacement::IWord(0); if let Some(base_reg) = idx.base { diff --git a/src/interpreter/register.rs b/src/interpreter/register.rs index e91a22f..bbd6743 100644 --- a/src/interpreter/register.rs +++ b/src/interpreter/register.rs @@ -1,8 +1,6 @@ -use crate::operands::{Byte, Operand, Word}; +use crate::operands::{Byte, ImmediateOperand, Word}; use core::fmt; -use super::flags::Flags; - #[derive(Debug, Clone, Copy)] pub struct Register { pub ax: AX, @@ -30,31 +28,31 @@ impl Register { } /// Read value from a [`crate::register::Register`]. - pub fn read(&self, reg: crate::register::Register) -> Operand { + pub fn read(&self, reg: crate::register::Register) -> ImmediateOperand { match reg { - crate::register::Register::AX => Operand::Word(self.ax.read()), - crate::register::Register::BX => Operand::Word(self.bx.read()), - crate::register::Register::CX => Operand::Word(self.cx.read()), - crate::register::Register::DX => Operand::Word(self.dx.read()), - crate::register::Register::AH => Operand::Byte(self.ax.upper), - crate::register::Register::AL => Operand::Byte(self.ax.lower), - crate::register::Register::BH => Operand::Byte(self.bx.upper), - crate::register::Register::BL => Operand::Byte(self.bx.lower), - crate::register::Register::CH => Operand::Byte(self.cx.upper), - crate::register::Register::CL => Operand::Byte(self.cx.lower), - crate::register::Register::DH => Operand::Byte(self.dx.upper), - crate::register::Register::DL => Operand::Byte(self.dx.lower), - crate::register::Register::DI => Operand::Word(self.di), - crate::register::Register::SI => Operand::Word(self.si), - crate::register::Register::BP => Operand::Word(self.bp), - crate::register::Register::SP => Operand::Word(self.sp), + crate::register::Register::AX => ImmediateOperand::Word(self.ax.read()), + crate::register::Register::BX => ImmediateOperand::Word(self.bx.read()), + crate::register::Register::CX => ImmediateOperand::Word(self.cx.read()), + crate::register::Register::DX => ImmediateOperand::Word(self.dx.read()), + crate::register::Register::AH => ImmediateOperand::Byte(self.ax.upper), + crate::register::Register::AL => ImmediateOperand::Byte(self.ax.lower), + crate::register::Register::BH => ImmediateOperand::Byte(self.bx.upper), + crate::register::Register::BL => ImmediateOperand::Byte(self.bx.lower), + crate::register::Register::CH => ImmediateOperand::Byte(self.cx.upper), + crate::register::Register::CL => ImmediateOperand::Byte(self.cx.lower), + crate::register::Register::DH => ImmediateOperand::Byte(self.dx.upper), + crate::register::Register::DL => ImmediateOperand::Byte(self.dx.lower), + crate::register::Register::DI => ImmediateOperand::Word(self.di), + crate::register::Register::SI => ImmediateOperand::Word(self.si), + crate::register::Register::BP => ImmediateOperand::Word(self.bp), + crate::register::Register::SP => ImmediateOperand::Word(self.sp), } } - /// Write an [`Operand`] to a [`crate::register::Register`]. - pub fn write(&mut self, reg: crate::register::Register, op: Operand) { + /// Write an [`ImmediateOperand`] to a [`crate::register::Register`]. + pub fn write(&mut self, reg: crate::register::Register, op: ImmediateOperand) { match op { - Operand::Byte(byte) => match reg { + ImmediateOperand::Byte(byte) => match reg { crate::register::Register::AX => self.ax.lower = byte, crate::register::Register::BX => self.bx.lower = byte, crate::register::Register::CX => self.cx.lower = byte, @@ -72,7 +70,7 @@ impl Register { crate::register::Register::BP => self.bp = Word::from_le_bytes([0x0, byte]), crate::register::Register::SP => self.sp = Word::from_le_bytes([0x0, byte]), }, - Operand::Word(word) => { + ImmediateOperand::Word(word) => { match reg { crate::register::Register::AX => self.ax.write(word), crate::register::Register::BX => self.bx.write(word), diff --git a/src/operands.rs b/src/operands.rs index 9654d90..f9d137b 100644 --- a/src/operands.rs +++ b/src/operands.rs @@ -20,70 +20,75 @@ pub type DWord = u32; /// Also sometimes used to decide if an instruction is Byte- or Word-sized, /// which is usually indicated by using a value of 0 and the disregarding /// the value when read. -pub enum Operand { +pub enum ImmediateOperand { Byte(Byte), Word(Word), } -impl Add for Operand { +impl Add for ImmediateOperand { type Output = Self; fn add(self, other: Self) -> Self { match self { - Operand::Byte(lhsb) => match other { - Operand::Byte(rhsb) => Operand::Byte(lhsb.wrapping_add(rhsb)), + ImmediateOperand::Byte(lhsb) => match other { + ImmediateOperand::Byte(rhsb) => ImmediateOperand::Byte(lhsb.wrapping_add(rhsb)), _ => panic!("Cannot add Word to Byte"), }, - Operand::Word(lhsw) => match other { - Operand::Word(rhsw) => Operand::Word(lhsw.wrapping_add(rhsw)), - Operand::Byte(rhsb) => Operand::Word(lhsw.wrapping_add(rhsb as Word)), + ImmediateOperand::Word(lhsw) => match other { + ImmediateOperand::Word(rhsw) => ImmediateOperand::Word(lhsw.wrapping_add(rhsw)), + ImmediateOperand::Byte(rhsb) => { + ImmediateOperand::Word(lhsw.wrapping_add(rhsb as Word)) + } }, } } } -impl Add for Operand { - type Output = Operand; +impl Add for ImmediateOperand { + type Output = ImmediateOperand; fn add(self, disp: Displacement) -> Self::Output { - // XXX: ugly hack to add Operand with Displacement + // Warning: this gets rid of the sign, which is fine as long as it is + // used for a memory index, which can never be negative. match disp { Displacement::IByte(byte) => { if byte < 0 { - return self - Operand::Byte((byte * -1) as Byte); + return self - ImmediateOperand::Byte((byte * -1) as Byte); } else { - return self + Operand::Byte(byte as Byte); + return self + ImmediateOperand::Byte(byte as Byte); } } Displacement::IWord(word) => { if word < 0 { - return self - Operand::Word((word * -1) as Word); + return self - ImmediateOperand::Word((word * -1) as Word); } else { - return self + Operand::Word(word as Word); + return self + ImmediateOperand::Word(word as Word); } } } } } -impl Sub for Operand { +impl Sub for ImmediateOperand { type Output = Self; fn sub(self, other: Self) -> Self { match self { - Operand::Byte(lhsb) => match other { - Operand::Byte(rhsb) => Operand::Byte(lhsb.wrapping_sub(rhsb)), + ImmediateOperand::Byte(lhsb) => match other { + ImmediateOperand::Byte(rhsb) => ImmediateOperand::Byte(lhsb.wrapping_sub(rhsb)), _ => panic!("Cannot substract Word from Byte"), }, - Operand::Word(lhsw) => match other { - Operand::Word(rhsw) => Operand::Word(lhsw.wrapping_sub(rhsw)), - Operand::Byte(rhsb) => Operand::Word(lhsw.wrapping_sub(rhsb as Word)), + ImmediateOperand::Word(lhsw) => match other { + ImmediateOperand::Word(rhsw) => ImmediateOperand::Word(lhsw.wrapping_sub(rhsw)), + ImmediateOperand::Byte(rhsb) => { + ImmediateOperand::Word(lhsw.wrapping_sub(rhsb as Word)) + } }, } } } -impl fmt::Display for Operand { +impl fmt::Display for ImmediateOperand { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Byte(byte) => write!(f, "{}", byte), @@ -92,7 +97,7 @@ impl fmt::Display for Operand { } } -impl fmt::LowerHex for Operand { +impl fmt::LowerHex for ImmediateOperand { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Byte(b) => fmt::LowerHex::fmt(b, f), diff --git a/src/register.rs b/src/register.rs index d730bfd..2561ca0 100644 --- a/src/register.rs +++ b/src/register.rs @@ -1,6 +1,6 @@ //! Internal abstraction of all 8086 registers for disassembly. -use crate::{disasm::DisasmError, operands::Operand}; +use crate::{disasm::DisasmError, operands::ImmediateOperand}; use core::fmt; #[derive(Debug, Clone, PartialEq, Eq, Copy)] @@ -34,9 +34,9 @@ pub type RegisterId = u8; impl Register { /// Find the register corresponding to the 8086 bytecode ID - pub fn by_id(id: Operand) -> Result { + pub fn by_id(id: ImmediateOperand) -> Result { match id { - Operand::Byte(b) => match b { + ImmediateOperand::Byte(b) => match b { 0b000 => Ok(Self::AL), 0b001 => Ok(Self::CL), 0b010 => Ok(Self::DL), @@ -47,7 +47,7 @@ impl Register { 0b111 => Ok(Self::BH), _ => Err(DisasmError::UnknownRegister(b as usize)), }, - Operand::Word(w) => match w { + ImmediateOperand::Word(w) => match w { 0b000 => Ok(Self::AX), 0b001 => Ok(Self::CX), 0b010 => Ok(Self::DX),