ft: implement some more instructions

This commit is contained in:
2025-05-14 20:38:51 +09:00
parent 22d7c5571f
commit 45ab158b95
2 changed files with 103 additions and 40 deletions

View File

@@ -2,7 +2,7 @@ use core::fmt;
use std::{fs::File, io::Read, process::exit}; use std::{fs::File, io::Read, process::exit};
use crate::aout::Aout; 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::register::{Register, RegisterId, SegmentRegister};
use crate::{ use crate::{
Args, Args,
@@ -135,7 +135,7 @@ impl Disassembler {
0b00 => { 0b00 => {
if rm == 0b110 { if rm == 0b110 {
log::debug!("Additional word during ModRM parsing was read with mod 0."); 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 ( return (
ModRmTarget::Memory(MemoryIndex { ModRmTarget::Memory(MemoryIndex {
base: None, base: None,
@@ -150,11 +150,11 @@ impl Disassembler {
} }
0b01 => { 0b01 => {
log::debug!("Additional byte during ModRM parsing was read."); 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 => { 0b10 => {
log::debug!("Additional word during ModRM parsing was read."); 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 => { 0b11 => {
log::debug!("ModRM ({:#b}) to/from Register ({:#b})", rm, reg); log::debug!("ModRM ({:#b}) to/from Register ({:#b})", rm, reg);
@@ -442,44 +442,44 @@ impl Disassembler {
0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)), 0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)),
0x70 => Mnemonic::JO(self.parse_byte()), 0x70 => Mnemonic::JO(self.parse_byte() as IByte),
0x71 => Mnemonic::JNO(self.parse_byte()), 0x71 => Mnemonic::JNO(self.parse_byte() as IByte),
0x72 => Mnemonic::JB(self.parse_byte()), 0x72 => Mnemonic::JB(self.parse_byte() as IByte),
0x73 => Mnemonic::JNB(self.parse_byte()), 0x73 => Mnemonic::JNB(self.parse_byte() as IByte),
0x74 => Mnemonic::JZ(self.parse_byte()), 0x74 => Mnemonic::JZ(self.parse_byte() as IByte),
0x75 => Mnemonic::JNZ(self.parse_byte()), 0x75 => Mnemonic::JNZ(self.parse_byte() as IByte),
0x76 => Mnemonic::JBE(self.parse_byte()), 0x76 => Mnemonic::JBE(self.parse_byte() as IByte),
0x77 => Mnemonic::JA(self.parse_byte()), 0x77 => Mnemonic::JA(self.parse_byte() as IByte),
0x78 => Mnemonic::JS(self.parse_byte()), 0x78 => Mnemonic::JS(self.parse_byte() as IByte),
0x79 => Mnemonic::JNS(self.parse_byte()), 0x79 => Mnemonic::JNS(self.parse_byte() as IByte),
0x7A => Mnemonic::JPE(self.parse_byte()), 0x7A => Mnemonic::JPE(self.parse_byte() as IByte),
0x7B => Mnemonic::JPO(self.parse_byte()), 0x7B => Mnemonic::JPO(self.parse_byte() as IByte),
0x7C => Mnemonic::JL(self.parse_byte()), 0x7C => Mnemonic::JL(self.parse_byte() as IByte),
0x7D => Mnemonic::JGE(self.parse_byte()), 0x7D => Mnemonic::JGE(self.parse_byte() as IByte),
0x7E => Mnemonic::JLE(self.parse_byte()), 0x7E => Mnemonic::JLE(self.parse_byte() as IByte),
0x7F => Mnemonic::JG(self.parse_byte()), 0x7F => Mnemonic::JG(self.parse_byte() as IByte),
// Group 1 // Group 1
0x80 => { 0x80 => {
let (target, reg) = self.parse_modrm_byte(Operand::Byte(0)); 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)) Self::modrm_reg_to_grp1(reg, target, Displacement::IByte(imm))
} }
0x81 => { 0x81 => {
let (target, reg) = self.parse_modrm_byte(Operand::Word(0)); 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)) Self::modrm_reg_to_grp1(reg, target, Displacement::IWord(imm))
} }
0x82 => { 0x82 => {
// same as 0x80 // same as 0x80
let (target, reg) = self.parse_modrm_byte(Operand::Byte(0)); 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)) Self::modrm_reg_to_grp1(reg, target, Displacement::IByte(imm))
} }
0x83 => { 0x83 => {
// byte extended version // byte extended version
let (target, reg) = self.parse_modrm_byte(Operand::Word(0)); 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)) 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"), 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)), 0xC8..=0xC9 => return Err(DisasmError::OpcodeUndefined(opcode)),
0xCD => Mnemonic::INT(self.parse_byte()), 0xCD => Mnemonic::INT(self.parse_byte()),
@@ -597,6 +606,16 @@ impl Disassembler {
Self::modrm_reg_to_grp2_cl(reg, target) 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()), 0xE8 => Mnemonic::CALL_v(self.parse_word()),
0xE9 => Mnemonic::JMP_v(self.parse_word()), 0xE9 => Mnemonic::JMP_v(self.parse_word()),
@@ -606,6 +625,15 @@ impl Disassembler {
}), }),
0xEB => Mnemonic::JMP_b(self.parse_byte()), 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, 0xF4 => Mnemonic::HLT,
// Group 3 // Group 3
@@ -618,6 +646,13 @@ impl Disassembler {
self.modrm_reg_to_grp3(reg, target, Operand::Word(0)) 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 => { 0xFE => {
let (target, reg) = self.parse_modrm_byte(Operand::Byte(0)); let (target, reg) = self.parse_modrm_byte(Operand::Byte(0));
match reg { match reg {

View File

@@ -165,22 +165,27 @@ pub enum Mnemonic {
DEC_Reg(Register), DEC_Reg(Register),
DEC_Mod(ModRmTarget), DEC_Mod(ModRmTarget),
// Jumps // Jumps
JO(Byte), JO(IByte),
JNO(Byte), JNO(IByte),
JB(Byte), JB(IByte),
JNB(Byte), JNB(IByte),
JZ(Byte), JZ(IByte),
JNZ(Byte), JNZ(IByte),
JBE(Byte), JBE(IByte),
JA(Byte), JA(IByte),
JS(Byte), JS(IByte),
JNS(Byte), JNS(IByte),
JPE(Byte), JPE(IByte),
JPO(Byte), JPO(IByte),
JL(Byte), JL(IByte),
JGE(Byte), JGE(IByte),
JLE(Byte), JLE(IByte),
JG(Byte), JG(IByte),
LOOPNZ(IByte),
LOOPZ(IByte),
LOOP(IByte),
JCXZ(IByte),
// TEST // TEST
TEST(ModRmTarget, Register), TEST(ModRmTarget, Register),
TEST_Ib(ModRmTarget, Byte), TEST_Ib(ModRmTarget, Byte),
@@ -195,6 +200,9 @@ pub enum Mnemonic {
MOV_ToReg(ModRmTarget, Register), MOV_ToReg(ModRmTarget, Register),
MOV_FromSReg(ModRmTarget, SegmentRegister), MOV_FromSReg(ModRmTarget, SegmentRegister),
MOV_ToSReg(ModRmTarget, SegmentRegister), MOV_ToSReg(ModRmTarget, SegmentRegister),
MOV_Ib(ModRmTarget, Byte),
MOV_Iv(ModRmTarget, Word),
MOV_AL0b(Byte), MOV_AL0b(Byte),
MOV_AX0v(Word), MOV_AX0v(Word),
MOV_0bAL(Byte), MOV_0bAL(Byte),
@@ -281,8 +289,28 @@ pub enum Mnemonic {
SHL_fromReg(ModRmTarget, Register), SHL_fromReg(ModRmTarget, Register),
SHR_fromReg(ModRmTarget, Register), SHR_fromReg(ModRmTarget, Register),
SAR_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
INT(Byte), INT(Byte),
// Flag Manipulation
CLC,
STC,
CLI,
STI,
CLD,
STD,
// Repeat prefix
REPNZ,
REPZ,
} }
impl fmt::Display for Mnemonic { impl fmt::Display for Mnemonic {