diff --git a/src/disasm.rs b/src/disasm.rs index e9a731f..692c588 100644 --- a/src/disasm.rs +++ b/src/disasm.rs @@ -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"), diff --git a/src/disasm_macros.rs b/src/disasm_macros.rs index 4f7cb46..e4f47bb 100644 --- a/src/disasm_macros.rs +++ b/src/disasm_macros.rs @@ -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)) }}; } diff --git a/src/instructions.rs b/src/instructions.rs index 3c30472..12e8c0d 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -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, pub index: Option, - pub displacement: Option, + pub displacement: Option, } 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 { diff --git a/src/register.rs b/src/register.rs index da0fcdb..08c6c3a 100644 --- a/src/register.rs +++ b/src/register.rs @@ -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,