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 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 {

View File

@@ -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 {