diff --git a/src/disasm.rs b/src/disasm.rs index 49f486a..e9a731f 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}; +use crate::instructions::{ImmediateOperand, MemoryIndex, ModRmTarget, Pointer}; use crate::register::{Register, RegisterId, SegmentRegister}; use crate::{ Args, @@ -143,7 +143,7 @@ impl Disassembler { displacement = Some(ImmediateOperand::Word(self.parse_word())); } 0b11 => { - log::debug!("ModRM to 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) let target = match width { ImmediateOperand::Byte(_) => { @@ -409,6 +409,39 @@ impl Disassembler { 0x8D => modrmv!(self, LEA), + 0x8F => { + let target = self.parse_modrm_byte(ImmediateOperand::Word(0)).0; + let mem = match target { + ModRmTarget::Memory(idx) => idx, + _ => panic!("POP_M instruction given a register to pop into"), + }; + Mnemonic::POP_M(mem) + } + 0x90 => Mnemonic::NOP(), + + 0x91 => Mnemonic::XCHG_AX(Register::CX), + 0x92 => Mnemonic::XCHG_AX(Register::DX), + 0x93 => Mnemonic::XCHG_AX(Register::BX), + 0x94 => Mnemonic::XCHG_AX(Register::SP), + 0x95 => Mnemonic::XCHG_AX(Register::BP), + 0x96 => Mnemonic::XCHG_AX(Register::SI), + 0x97 => Mnemonic::XCHG_AX(Register::DI), + + 0x98 => Mnemonic::CBW, + 0x99 => Mnemonic::CWD, + + 0x9A => Mnemonic::CALL(Pointer { + segment: self.parse_word(), + offset: self.parse_word(), + }), + + 0x9B => Mnemonic::WAIT, + + 0x9C => Mnemonic::PUSHF, + 0x9D => Mnemonic::POPF, + 0x9E => Mnemonic::SAHF, + 0x9F => Mnemonic::LAHF, + 0xCD => Mnemonic::INT(self.parse_byte()), 0xBB => Mnemonic::MOV_BXIv(self.parse_word()), diff --git a/src/instructions.rs b/src/instructions.rs index 5672690..3c30472 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -68,18 +68,19 @@ impl fmt::Display for Instruction { pub enum Mnemonic { NOP(), // ADD - ADD_FromReg(ModRmTarget, Register), - ADD_ToReg(ModRmTarget, Register), - ADD_Ib(ModRmTarget, ImmediateByte), - ADD_Iv(ModRmTarget, ImmediateWord), + 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), // PUSH PUSH_R(Register), PUSH_S(SegmentRegister), // POP - POP_S(SegmentRegister), - POP_R(Register), + POP_S(SegmentRegister), // POP to Segment Register + POP_R(Register), // POP to Register + POP_M(MemoryIndex), // POP to Memory // OR OR_FromReg(ModRmTarget, Register), OR_ToReg(ModRmTarget, Register), @@ -161,6 +162,7 @@ pub enum Mnemonic { TEST(ModRmTarget, Register), //XHCG XHCG(ModRmTarget, Register), + XCHG_AX(Register), // from AX // MOV MOV_FromReg(ModRmTarget, Register), MOV_ToReg(ModRmTarget, Register), @@ -169,6 +171,18 @@ pub enum Mnemonic { MOV_BXIv(ImmediateWord), // LEA LEA(ModRmTarget, Register), + // Sign extensions + CBW, + CWD, + // CALL + CALL(Pointer), + // WAIT + WAIT, + // Push/Pop Flags + PUSHF, + POPF, + SAHF, + LAHF, // INT INT(ImmediateByte), } @@ -182,6 +196,7 @@ impl fmt::Display for Mnemonic { Self::CMP_Iv(mem, imm) => write!(f, "cmp {}, {:04x}", mem, imm), Self::LEA(mem, reg) => write!(f, "lea {}, {}", reg, mem), Self::MOV_BXIv(word) => write!(f, "mov bx, {:04x}", word), + Self::MOV_FromReg(target, reg) => write!(f, "mov {}, {}", target, reg), Self::XOR_FromReg(mem, reg) => write!(f, "xor {}, {}", mem, reg), _ => write!(f, "??? ??, ??"), } @@ -236,3 +251,16 @@ 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, +} + +impl std::fmt::Display for Pointer { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}:{}", self.segment, self.offset) + } +}