From 4fa789e6bb257b54cc0f67cefd0ceb66d5b33f60 Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Wed, 14 May 2025 13:35:00 +0900 Subject: [PATCH] ft: Implement Group 4 Instructions --- src/disasm.rs | 59 +++++++++++++++++++++++++++++---------------- src/instructions.rs | 6 +++-- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/disasm.rs b/src/disasm.rs index cd6c6c5..1b3b489 100644 --- a/src/disasm.rs +++ b/src/disasm.rs @@ -15,6 +15,7 @@ use crate::{modrmb, modrms, modrmv}; pub enum DisasmError { NoFile(Option), IoError(std::io::Error), + OpcodeUndefined(u8), } impl From for DisasmError { @@ -28,6 +29,11 @@ impl fmt::Display for DisasmError { match self { DisasmError::NoFile(msg) => write!(f, "No file error: {:?}", msg), DisasmError::IoError(msg) => write!(f, "{}", msg), + DisasmError::OpcodeUndefined(opcode) => write!( + f, + "Instruction '{:#x} is considered undefined by the Spec", + opcode + ), } } } @@ -327,7 +333,8 @@ impl Disassembler { 0x0D => Mnemonic::OR_AXIv(self.parse_word()), 0x0E => Mnemonic::PUSH_S(SegmentRegister::CS), - 0x0F => panic!("Opcode 0x0F (POP CS) is considered undefined"), + + 0x0F => return Err(DisasmError::OpcodeUndefined(opcode)), 0x10 => modrmb!(self, ADC_FromReg), 0x11 => modrmv!(self, ADC_FromReg), @@ -389,23 +396,23 @@ impl Disassembler { 0x3E => Mnemonic::OVERRIDE(SegmentRegister::DS), 0x3F => Mnemonic::AAS, - 0x40 => Mnemonic::INC(Register::AX), - 0x41 => Mnemonic::INC(Register::CX), - 0x42 => Mnemonic::INC(Register::DX), - 0x43 => Mnemonic::INC(Register::BX), - 0x44 => Mnemonic::INC(Register::SP), - 0x45 => Mnemonic::INC(Register::BP), - 0x46 => Mnemonic::INC(Register::SI), - 0x47 => Mnemonic::INC(Register::DI), + 0x40 => Mnemonic::INC_Reg(Register::AX), + 0x41 => Mnemonic::INC_Reg(Register::CX), + 0x42 => Mnemonic::INC_Reg(Register::DX), + 0x43 => Mnemonic::INC_Reg(Register::BX), + 0x44 => Mnemonic::INC_Reg(Register::SP), + 0x45 => Mnemonic::INC_Reg(Register::BP), + 0x46 => Mnemonic::INC_Reg(Register::SI), + 0x47 => Mnemonic::INC_Reg(Register::DI), - 0x48 => Mnemonic::DEC(Register::AX), - 0x49 => Mnemonic::DEC(Register::CX), - 0x4A => Mnemonic::DEC(Register::DX), - 0x4B => Mnemonic::DEC(Register::BX), - 0x4C => Mnemonic::DEC(Register::SP), - 0x4D => Mnemonic::DEC(Register::BP), - 0x4E => Mnemonic::DEC(Register::SI), - 0x4F => Mnemonic::DEC(Register::DI), + 0x48 => Mnemonic::DEC_Reg(Register::AX), + 0x49 => Mnemonic::DEC_Reg(Register::CX), + 0x4A => Mnemonic::DEC_Reg(Register::DX), + 0x4B => Mnemonic::DEC_Reg(Register::BX), + 0x4C => Mnemonic::DEC_Reg(Register::SP), + 0x4D => Mnemonic::DEC_Reg(Register::BP), + 0x4E => Mnemonic::DEC_Reg(Register::SI), + 0x4F => Mnemonic::DEC_Reg(Register::DI), 0x50 => Mnemonic::PUSH_R(Register::AX), 0x51 => Mnemonic::PUSH_R(Register::CX), @@ -425,7 +432,7 @@ impl Disassembler { 0x5E => Mnemonic::POP_R(Register::SI), 0x5F => Mnemonic::POP_R(Register::DI), - 0x60..=0x6F => panic!("{:#x} is considered undefined", opcode), + 0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)), 0x70 => Mnemonic::JO(self.parse_byte()), 0x71 => Mnemonic::JNO(self.parse_byte()), @@ -548,14 +555,14 @@ impl Disassembler { 0xBE => Mnemonic::MOV_SIIv(self.parse_word()), 0xBF => Mnemonic::MOV_DIIv(self.parse_word()), - 0xC0..=0xC1 => panic!("{:#x} is considered in undefined", opcode), + 0xC0..=0xC1 => return Err(DisasmError::OpcodeUndefined(opcode)), 0xC2 => Mnemonic::RETIw(self.parse_word()), 0xC3 => Mnemonic::RET, - 0xC4..=0xC5 => panic!("{:#x} not yet implemented (LDS or LES)", opcode), + 0xC4..=0xC5 => todo!("LES and LDS not yet implemented"), - 0xC8..=0xC9 => panic!("{:#x} is considered in undefined", opcode), + 0xC8..=0xC9 => return Err(DisasmError::OpcodeUndefined(opcode)), 0xCD => Mnemonic::INT(self.parse_byte()), @@ -598,6 +605,16 @@ impl Disassembler { self.modrm_reg_to_grp3(reg, target, Operand::Word(0)) } + 0xFE => { + let (target, reg) = self.parse_modrm_byte(Operand::Byte(0)); + match reg { + 0b0 => Mnemonic::INC_Mod(target), + 0b1 => Mnemonic::DEC_Mod(target), + _ => panic!("Illegal Group 4 mnemonic"), + } + } + 0xFF => todo!("Group 5"), + _ => { eprintln!("Encountered unknown instruction '0x{:x}'", opcode); eprintln!("Offset might be misaligned and data is being interpreted."); diff --git a/src/instructions.rs b/src/instructions.rs index ac30ebb..41f6e0f 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -138,9 +138,11 @@ pub enum Mnemonic { CMP_ALIb(Byte), CMP_AXIv(Word), // INC - INC(Register), + INC_Reg(Register), + INC_Mod(ModRmTarget), // DEC - DEC(Register), + DEC_Reg(Register), + DEC_Mod(ModRmTarget), // Jumps JO(Byte), JNO(Byte),