From 45ab158b951c3994bdeb833a08c66114cc8ac5e4 Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Wed, 14 May 2025 20:38:51 +0900 Subject: [PATCH] ft: implement some more instructions --- src/disasm.rs | 83 ++++++++++++++++++++++++++++++++------------- src/instructions.rs | 60 +++++++++++++++++++++++--------- 2 files changed, 103 insertions(+), 40 deletions(-) diff --git a/src/disasm.rs b/src/disasm.rs index f31dde9..ce10b0c 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::{Displacement, MemoryIndex, ModRmTarget, Operand, Pointer}; +use crate::instructions::{Displacement, IByte, IWord, MemoryIndex, ModRmTarget, Operand, Pointer}; use crate::register::{Register, RegisterId, SegmentRegister}; use crate::{ Args, @@ -135,7 +135,7 @@ impl Disassembler { 0b00 => { if rm == 0b110 { log::debug!("Additional word during ModRM parsing was read with mod 0."); - displacement = Some(Displacement::IWord(self.parse_word() as i16)); + displacement = Some(Displacement::IWord(self.parse_word() as IWord)); return ( ModRmTarget::Memory(MemoryIndex { base: None, @@ -150,11 +150,11 @@ impl Disassembler { } 0b01 => { log::debug!("Additional byte during ModRM parsing was read."); - displacement = Some(Displacement::IByte(self.parse_byte() as i8)) + displacement = Some(Displacement::IByte(self.parse_byte() as IByte)) } 0b10 => { log::debug!("Additional word during ModRM parsing was read."); - displacement = Some(Displacement::IWord(self.parse_word() as i16)); + displacement = Some(Displacement::IWord(self.parse_word() as IWord)); } 0b11 => { log::debug!("ModRM ({:#b}) to/from Register ({:#b})", rm, reg); @@ -442,44 +442,44 @@ impl Disassembler { 0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)), - 0x70 => Mnemonic::JO(self.parse_byte()), - 0x71 => Mnemonic::JNO(self.parse_byte()), - 0x72 => Mnemonic::JB(self.parse_byte()), - 0x73 => Mnemonic::JNB(self.parse_byte()), - 0x74 => Mnemonic::JZ(self.parse_byte()), - 0x75 => Mnemonic::JNZ(self.parse_byte()), - 0x76 => Mnemonic::JBE(self.parse_byte()), - 0x77 => Mnemonic::JA(self.parse_byte()), - 0x78 => Mnemonic::JS(self.parse_byte()), - 0x79 => Mnemonic::JNS(self.parse_byte()), - 0x7A => Mnemonic::JPE(self.parse_byte()), - 0x7B => Mnemonic::JPO(self.parse_byte()), - 0x7C => Mnemonic::JL(self.parse_byte()), - 0x7D => Mnemonic::JGE(self.parse_byte()), - 0x7E => Mnemonic::JLE(self.parse_byte()), - 0x7F => Mnemonic::JG(self.parse_byte()), + 0x70 => Mnemonic::JO(self.parse_byte() as IByte), + 0x71 => Mnemonic::JNO(self.parse_byte() as IByte), + 0x72 => Mnemonic::JB(self.parse_byte() as IByte), + 0x73 => Mnemonic::JNB(self.parse_byte() as IByte), + 0x74 => Mnemonic::JZ(self.parse_byte() as IByte), + 0x75 => Mnemonic::JNZ(self.parse_byte() as IByte), + 0x76 => Mnemonic::JBE(self.parse_byte() as IByte), + 0x77 => Mnemonic::JA(self.parse_byte() as IByte), + 0x78 => Mnemonic::JS(self.parse_byte() as IByte), + 0x79 => Mnemonic::JNS(self.parse_byte() as IByte), + 0x7A => Mnemonic::JPE(self.parse_byte() as IByte), + 0x7B => Mnemonic::JPO(self.parse_byte() as IByte), + 0x7C => Mnemonic::JL(self.parse_byte() as IByte), + 0x7D => Mnemonic::JGE(self.parse_byte() as IByte), + 0x7E => Mnemonic::JLE(self.parse_byte() as IByte), + 0x7F => Mnemonic::JG(self.parse_byte() as IByte), // Group 1 0x80 => { let (target, reg) = self.parse_modrm_byte(Operand::Byte(0)); - let imm = self.parse_byte() as i8; + let imm = self.parse_byte() as IByte; Self::modrm_reg_to_grp1(reg, target, Displacement::IByte(imm)) } 0x81 => { let (target, reg) = self.parse_modrm_byte(Operand::Word(0)); - let imm = self.parse_word() as i16; + let imm = self.parse_word() as IWord; Self::modrm_reg_to_grp1(reg, target, Displacement::IWord(imm)) } 0x82 => { // same as 0x80 let (target, reg) = self.parse_modrm_byte(Operand::Byte(0)); - let imm = self.parse_byte() as i8; + let imm = self.parse_byte() as IByte; Self::modrm_reg_to_grp1(reg, target, Displacement::IByte(imm)) } 0x83 => { // byte extended version let (target, reg) = self.parse_modrm_byte(Operand::Word(0)); - let imm = self.parse_byte() as i8; + let imm = self.parse_byte() as IByte; Self::modrm_reg_to_grp1(reg, target, Displacement::IByte(imm)) } @@ -575,6 +575,15 @@ impl Disassembler { 0xC4..=0xC5 => todo!("LES and LDS not yet implemented"), + 0xC6 => { + let (target, _) = self.parse_modrm_byte(Operand::Byte(0)); + Mnemonic::MOV_Ib(target, self.parse_byte()) + } + 0xC7 => { + let (target, _) = self.parse_modrm_byte(Operand::Word(0)); + Mnemonic::MOV_Iv(target, self.parse_word()) + } + 0xC8..=0xC9 => return Err(DisasmError::OpcodeUndefined(opcode)), 0xCD => Mnemonic::INT(self.parse_byte()), @@ -597,6 +606,16 @@ impl Disassembler { Self::modrm_reg_to_grp2_cl(reg, target) } + 0xE0 => Mnemonic::LOOPNZ(self.parse_byte() as IByte), + 0xE1 => Mnemonic::LOOPZ(self.parse_byte() as IByte), + 0xE2 => Mnemonic::LOOP(self.parse_byte() as IByte), + 0xE3 => Mnemonic::JCXZ(self.parse_byte() as IByte), + + 0xE4 => Mnemonic::IN_AL(self.parse_byte()), + 0xE5 => Mnemonic::IN_AX(self.parse_byte()), + 0xE6 => Mnemonic::OUT_AL(self.parse_byte()), + 0xE7 => Mnemonic::OUT_AX(self.parse_byte()), + 0xE8 => Mnemonic::CALL_v(self.parse_word()), 0xE9 => Mnemonic::JMP_v(self.parse_word()), @@ -606,6 +625,15 @@ impl Disassembler { }), 0xEB => Mnemonic::JMP_b(self.parse_byte()), + 0xEC => Mnemonic::IN_ALDX, + 0xED => Mnemonic::IN_AXDX, + + 0xEE => Mnemonic::OUT_ALDX, + 0xEF => Mnemonic::OUT_AXDX, + + 0xF2 => Mnemonic::REPNZ, + 0xF3 => Mnemonic::REPZ, + 0xF4 => Mnemonic::HLT, // Group 3 @@ -618,6 +646,13 @@ impl Disassembler { self.modrm_reg_to_grp3(reg, target, Operand::Word(0)) } + 0xF8 => Mnemonic::CLC, + 0xF9 => Mnemonic::STC, + 0xFA => Mnemonic::CLI, + 0xFB => Mnemonic::STI, + 0xFC => Mnemonic::CLD, + 0xFD => Mnemonic::STD, + 0xFE => { let (target, reg) = self.parse_modrm_byte(Operand::Byte(0)); match reg { diff --git a/src/instructions.rs b/src/instructions.rs index fa4c795..5321ee0 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -165,22 +165,27 @@ pub enum Mnemonic { DEC_Reg(Register), DEC_Mod(ModRmTarget), // Jumps - 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), + JO(IByte), + JNO(IByte), + JB(IByte), + JNB(IByte), + JZ(IByte), + JNZ(IByte), + JBE(IByte), + JA(IByte), + JS(IByte), + JNS(IByte), + JPE(IByte), + JPO(IByte), + JL(IByte), + JGE(IByte), + JLE(IByte), + JG(IByte), + LOOPNZ(IByte), + LOOPZ(IByte), + LOOP(IByte), + JCXZ(IByte), + // TEST TEST(ModRmTarget, Register), TEST_Ib(ModRmTarget, Byte), @@ -195,6 +200,9 @@ pub enum Mnemonic { MOV_ToReg(ModRmTarget, Register), MOV_FromSReg(ModRmTarget, SegmentRegister), MOV_ToSReg(ModRmTarget, SegmentRegister), + MOV_Ib(ModRmTarget, Byte), + MOV_Iv(ModRmTarget, Word), + MOV_AL0b(Byte), MOV_AX0v(Word), MOV_0bAL(Byte), @@ -281,8 +289,28 @@ pub enum Mnemonic { SHL_fromReg(ModRmTarget, Register), SHR_fromReg(ModRmTarget, Register), SAR_fromReg(ModRmTarget, Register), + // IN + IN_AL(Byte), + IN_AX(Byte), + IN_ALDX, + IN_AXDX, + // OUT + OUT_AL(Byte), + OUT_AX(Byte), + OUT_ALDX, + OUT_AXDX, // INT INT(Byte), + // Flag Manipulation + CLC, + STC, + CLI, + STI, + CLD, + STD, + // Repeat prefix + REPNZ, + REPZ, } impl fmt::Display for Mnemonic {