ft: implement some more mnemonics

This commit is contained in:
2025-05-14 10:39:07 +09:00
parent f7446c14b1
commit a61b82fe22
2 changed files with 69 additions and 8 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::{ImmediateOperand, MemoryIndex, ModRmTarget}; use crate::instructions::{ImmediateOperand, MemoryIndex, ModRmTarget, Pointer};
use crate::register::{Register, RegisterId, SegmentRegister}; use crate::register::{Register, RegisterId, SegmentRegister};
use crate::{ use crate::{
Args, Args,
@@ -143,7 +143,7 @@ impl Disassembler {
displacement = Some(ImmediateOperand::Word(self.parse_word())); displacement = Some(ImmediateOperand::Word(self.parse_word()));
} }
0b11 => { 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) // XXX: find a nicer way instead of using Byte(0) and Word(0)
let target = match width { let target = match width {
ImmediateOperand::Byte(_) => { ImmediateOperand::Byte(_) => {
@@ -409,6 +409,39 @@ impl Disassembler {
0x8D => modrmv!(self, LEA), 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()), 0xCD => Mnemonic::INT(self.parse_byte()),
0xBB => Mnemonic::MOV_BXIv(self.parse_word()), 0xBB => Mnemonic::MOV_BXIv(self.parse_word()),

View File

@@ -68,18 +68,19 @@ impl fmt::Display for Instruction {
pub enum Mnemonic { pub enum Mnemonic {
NOP(), NOP(),
// ADD // ADD
ADD_FromReg(ModRmTarget, Register), ADD_FromReg(ModRmTarget, Register), // From Register into either Memory or Register
ADD_ToReg(ModRmTarget, Register), ADD_ToReg(ModRmTarget, Register), // From either Memory or Register into Reigster
ADD_Ib(ModRmTarget, ImmediateByte), ADD_Ib(ModRmTarget, ImmediateByte), // From Immediate into either Memory or Register
ADD_Iv(ModRmTarget, ImmediateWord), ADD_Iv(ModRmTarget, ImmediateWord), // From Immediate into either Memory or Register
ADD_ALIb(ImmediateByte), ADD_ALIb(ImmediateByte),
ADD_AXIv(ImmediateWord), ADD_AXIv(ImmediateWord),
// PUSH // PUSH
PUSH_R(Register), PUSH_R(Register),
PUSH_S(SegmentRegister), PUSH_S(SegmentRegister),
// POP // POP
POP_S(SegmentRegister), POP_S(SegmentRegister), // POP to Segment Register
POP_R(Register), POP_R(Register), // POP to Register
POP_M(MemoryIndex), // POP to Memory
// OR // OR
OR_FromReg(ModRmTarget, Register), OR_FromReg(ModRmTarget, Register),
OR_ToReg(ModRmTarget, Register), OR_ToReg(ModRmTarget, Register),
@@ -161,6 +162,7 @@ pub enum Mnemonic {
TEST(ModRmTarget, Register), TEST(ModRmTarget, Register),
//XHCG //XHCG
XHCG(ModRmTarget, Register), XHCG(ModRmTarget, Register),
XCHG_AX(Register), // from AX
// MOV // MOV
MOV_FromReg(ModRmTarget, Register), MOV_FromReg(ModRmTarget, Register),
MOV_ToReg(ModRmTarget, Register), MOV_ToReg(ModRmTarget, Register),
@@ -169,6 +171,18 @@ pub enum Mnemonic {
MOV_BXIv(ImmediateWord), MOV_BXIv(ImmediateWord),
// LEA // LEA
LEA(ModRmTarget, Register), LEA(ModRmTarget, Register),
// Sign extensions
CBW,
CWD,
// CALL
CALL(Pointer),
// WAIT
WAIT,
// Push/Pop Flags
PUSHF,
POPF,
SAHF,
LAHF,
// INT // INT
INT(ImmediateByte), INT(ImmediateByte),
} }
@@ -182,6 +196,7 @@ impl fmt::Display for Mnemonic {
Self::CMP_Iv(mem, imm) => write!(f, "cmp {}, {:04x}", mem, imm), Self::CMP_Iv(mem, imm) => write!(f, "cmp {}, {:04x}", mem, imm),
Self::LEA(mem, reg) => write!(f, "lea {}, {}", reg, mem), Self::LEA(mem, reg) => write!(f, "lea {}, {}", reg, mem),
Self::MOV_BXIv(word) => write!(f, "mov bx, {:04x}", word), 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), Self::XOR_FromReg(mem, reg) => write!(f, "xor {}, {}", mem, reg),
_ => write!(f, "??? ??, ??"), _ => 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)
}
}