ft: implement fmt::Display for all mnemonics

This commit is contained in:
2025-05-20 10:46:52 +09:00
parent fd15e57569
commit 3fe58e8bac
2 changed files with 235 additions and 12 deletions

View File

@@ -486,8 +486,8 @@ impl Disassembler {
0x84 => modrmb!(self, TEST),
0x85 => modrmv!(self, TEST),
0x86 => modrmb!(self, XHCG),
0x87 => modrmv!(self, XHCG),
0x86 => modrmb!(self, XCHG),
0x87 => modrmv!(self, XCHG),
0x88 => modrmb!(self, MOV_FromReg),
0x89 => modrmv!(self, MOV_FromReg),

View File

@@ -193,7 +193,7 @@ pub enum Mnemonic {
TEST_ALIb(Byte),
TEST_AXIv(Word),
//XHCG
XHCG(ModRmTarget, Register),
XCHG(ModRmTarget, Register),
XCHG_AX(Register), // from AX
// MOV
MOV_FromReg(ModRmTarget, Register),
@@ -326,15 +326,237 @@ pub enum Mnemonic {
impl fmt::Display for Mnemonic {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::INT(byte) => write!(f, "int, {:x}", byte),
Self::ADD_FromReg(mem, reg) => write!(f, "add {}, {}", mem, reg),
Self::ADD_ToReg(mem, reg) => write!(f, "add {}, {}", reg, mem),
Self::CMP_Iv(mem, imm) => write!(f, "cmp {}, {:04x}", mem, imm),
Self::CMP_Ib(target, imm) => write!(f, "cmp {}, {:04x}", target, imm),
Self::ADD_FromReg(target, reg) => write!(f, "add {target}, {reg}"),
Self::ADD_ToReg(target, reg) => write!(f, "add {reg}, {target}"),
Self::ADD_Ib(target, byte) => write!(f, "add {target}, {byte:#04x}"),
Self::ADD_Iv(target, word) => write!(f, "add {target}, {word:#04x}"),
Self::ADD_ALIb(byte) => write!(f, "add {}, {byte:#04x}", Register::AL),
Self::ADD_AXIv(word) => write!(f, "add {}, {word:#04x}", Register::AX),
Self::PUSH_R(reg) => write!(f, "push {reg}"),
Self::PUSH_S(reg) => write!(f, "push {reg}"),
Self::PUSH_Mod(target) => write!(f, "push {target}"),
Self::POP_R(reg) => write!(f, "pop {reg}"),
Self::POP_S(reg) => write!(f, "pop {reg}"),
Self::POP_M(mem) => write!(f, "pop {mem}"),
Self::OR_FromReg(target, reg) => write!(f, "or {target}, {reg}"),
Self::OR_ToReg(target, reg) => write!(f, "or {reg}, {target}"),
Self::OR_Ib(target, byte) => write!(f, "or {target}, {byte:#04x}"),
Self::OR_Iv(target, word) => write!(f, "or {target}, {word:#04x}"),
Self::OR_ALIb(byte) => write!(f, "or {}, {byte:#04x}", Register::AL),
Self::OR_AXIv(word) => write!(f, "or {}, {word:#04x}", Register::AX),
Self::ADC_FromReg(target, reg) => write!(f, "adc {target}, {reg}"),
Self::ADC_ToReg(target, reg) => write!(f, "adc {reg}, {target}"),
Self::ADC_Ib(target, byte) => write!(f, "adc {target}, {byte:#04x}"),
Self::ADC_Iv(target, word) => write!(f, "adc {target}, {word:#04x}"),
Self::ADC_ALIb(byte) => write!(f, "adc {}, {byte:#04x}", Register::AL),
Self::ADC_AXIv(word) => write!(f, "adc {}, {word:#04x}", Register::AX),
Self::SBB_FromReg(target, reg) => write!(f, "sbb {target}, {reg}"),
Self::SBB_ToReg(target, reg) => write!(f, "sbb {reg}, {target}"),
Self::SBB_Ib(target, byte) => write!(f, "sbb {target}, {byte:#04x}"),
Self::SBB_Iv(target, word) => write!(f, "sbb {target}, {word:#04x}"),
Self::SBB_ALIb(byte) => write!(f, "sbb {}, {byte:#04x}", Register::AL),
Self::SBB_AXIv(word) => write!(f, "sbb {}, {word:#04x}", Register::AX),
Self::AND_FromReg(target, reg) => write!(f, "and {target}, {reg}"),
Self::AND_ToReg(target, reg) => write!(f, "and {reg}, {target}"),
Self::AND_Ib(target, byte) => write!(f, "and {target}, {byte:#04x}"),
Self::AND_Iv(target, word) => write!(f, "and {target}, {word:#04x}"),
Self::AND_ALIb(byte) => write!(f, "and {}, {byte:#04x}", Register::AL),
Self::AND_AXIv(word) => write!(f, "and {}, {word:#04x}", Register::AX),
Self::OVERRIDE(reg) => write!(f, "{reg}:"),
Self::DAA => write!(f, "DAA"),
Self::DAS => write!(f, "DAS"),
Self::AAA => write!(f, "AAA"),
Self::AAS => write!(f, "AAS"),
Self::SUB_FromReg(target, reg) => write!(f, "sub {target}, {reg}"),
Self::SUB_ToReg(target, reg) => write!(f, "sub {reg}, {target}"),
Self::SUB_Ib(target, byte) => write!(f, "sub {target}, {byte:#04x}"),
Self::SUB_Iv(target, word) => write!(f, "sub {target}, {word:#04x}"),
Self::SUB_ALIb(byte) => write!(f, "sub {}, {byte:#04x}", Register::AL),
Self::SUB_AXIv(word) => write!(f, "sub {}, {word:#04x}", Register::AX),
Self::XOR_FromReg(target, reg) => write!(f, "xor {target}, {reg}"),
Self::XOR_ToReg(target, reg) => write!(f, "xor {reg}, {target}"),
Self::XOR_Ib(target, byte) => write!(f, "xor {target}, {byte:#04x}"),
Self::XOR_Iv(target, word) => write!(f, "xor {target}, {word:#04x}"),
Self::XOR_ALIb(byte) => write!(f, "xor {}, {byte:#04x}", Register::AL),
Self::XOR_AXIv(word) => write!(f, "xor {}, {word:#04x}", Register::AX),
Self::CMP_FromReg(target, reg) => write!(f, "cmp {target}, {reg}"),
Self::CMP_ToReg(target, reg) => write!(f, "cmp {reg}, {target}"),
Self::CMP_Ib(target, byte) => write!(f, "cmp {target}, {byte:#04x}"),
Self::CMP_Iv(target, word) => write!(f, "cmp {target}, {word:#04x}"),
Self::CMP_ALIb(byte) => write!(f, "cmp {}, {byte:#04x}", Register::AL),
Self::CMP_AXIv(word) => write!(f, "cmp {}, {word:#04x}", Register::AX),
Self::INC_Reg(reg) => write!(f, "INC {reg}"),
Self::INC_Mod(target) => write!(f, "INC {target}"),
Self::DEC_Reg(reg) => write!(f, "dec {reg}"),
Self::DEC_Mod(target) => write!(f, "dec {target}"),
Self::JO(ibyte) => write!(f, "jo {ibyte}"),
Self::JNO(ibyte) => write!(f, "jno {ibyte}"),
Self::JB(ibyte) => write!(f, "jb {ibyte}"),
Self::JNB(ibyte) => write!(f, "jnb {ibyte}"),
Self::JZ(ibyte) => write!(f, "jz {ibyte}"),
Self::JNZ(ibyte) => write!(f, "jnz {ibyte}"),
Self::JBE(ibyte) => write!(f, "jbe {ibyte}"),
Self::JA(ibyte) => write!(f, "ja {ibyte}"),
Self::JS(ibyte) => write!(f, "js {ibyte}"),
Self::JNS(ibyte) => write!(f, "jns {ibyte}"),
Self::JPE(ibyte) => write!(f, "jpe {ibyte}"),
Self::JPO(ibyte) => write!(f, "jpo {ibyte}"),
Self::JL(ibyte) => write!(f, "jl {ibyte}"),
Self::JGE(ibyte) => write!(f, "jge {ibyte}"),
Self::JLE(ibyte) => write!(f, "jle {ibyte}"),
Self::JG(ibyte) => write!(f, "jg {ibyte}"),
Self::LOOPNZ(ibyte) => write!(f, "loopnz {ibyte}"),
Self::LOOPZ(ibyte) => write!(f, "loopz {ibyte}"),
Self::LOOP(ibyte) => write!(f, "loop {ibyte}"),
Self::JCXZ(ibyte) => write!(f, "jcxz {ibyte}"),
Self::TEST(target, reg) => write!(f, "test {target}, {reg}"),
Self::TEST_Ib(target, byte) => write!(f, "test byte {target}, {byte:#04x}"),
Self::TEST_Iv(target, word) => write!(f, "test word {target}, {word:#04x}"),
Self::TEST_ALIb(byte) => write!(f, "test {}, {byte:#04x}", Register::AL),
Self::TEST_AXIv(word) => write!(f, "test {}, {word:#04x}", Register::AX),
Self::XCHG(target, reg) => write!(f, "xchg {target}, {reg}"),
Self::XCHG_AX(reg) => write!(f, "xchg, {reg}, {}", Register::AX),
Self::MOV_FromReg(target, reg) => write!(f, "mov {target}, {reg}"),
Self::MOV_ToReg(target, reg) => write!(f, "mov {reg}, {target}"),
Self::MOV_FromSReg(target, reg) => write!(f, "mov {target}, {reg}"),
Self::MOV_ToSReg(target, reg) => write!(f, "mov {reg}, {target}"),
Self::MOV_Ib(target, byte) => write!(f, "mov {target}, {byte:#04x}"),
Self::MOV_Iv(target, word) => write!(f, "mov {target}, {word:#04x}"),
Self::MOV_AL0b(byte) => write!(f, "mov {}, {byte:#04x}", Register::AL),
Self::MOV_AX0v(word) => write!(f, "mov {}, {word:#04x}", Register::AX),
Self::MOV_0bAL(byte) => write!(f, "mov {byte:#04x}, {}", Register::AL),
Self::MOV_0vAX(word) => write!(f, "mov {word:#04x}, {}", Register::AX),
Self::MOV_ALIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::AL),
Self::MOV_CLIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::CL),
Self::MOV_DLIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::DL),
Self::MOV_BLIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::BL),
Self::MOV_AHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::AH),
Self::MOV_CHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::CH),
Self::MOV_DHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::DH),
Self::MOV_BHIb(byte) => write!(f, "mov {}, {byte:#04x}", Register::BH),
Self::MOV_AXIv(word) => write!(f, "mov {}, {word:#04x}", Register::AX),
Self::MOV_CXIv(word) => write!(f, "mov {}, {word:#04x}", Register::CX),
Self::MOV_DXIv(word) => write!(f, "mov {}, {word:#04x}", Register::DX),
Self::MOV_BXIv(word) => write!(f, "mov {}, {word:#04x}", Register::BX),
Self::MOV_SPIv(word) => write!(f, "mov {}, {word:#04x}", Register::SP),
Self::MOV_BPIv(word) => write!(f, "mov {}, {word:#04x}", Register::BP),
Self::MOV_SIIv(word) => write!(f, "mov {}, {word:#04x}", Register::SI),
Self::MOV_DIIv(word) => write!(f, "mov {}, {word:#04x}", Register::DI),
Self::LEA(mem, reg) => write!(f, "lea {}, {}", reg, mem),
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::CBW => write!(f, "CBW"),
Self::CWD => write!(f, "CWD"),
Self::CALL_p(ptr) => write!(f, "call {ptr}"),
Self::CALL_v(word) => write!(f, "call {word:#04x}"),
Self::CALL_Mod(target) => write!(f, "call {target}"),
Self::JMP_p(ptr) => write!(f, "jmp {ptr}"),
Self::JMP_b(byte) => write!(f, "jmp {byte:#04}"),
Self::JMP_v(word) => write!(f, "jmp {word:#04}"),
Self::JMP_Mod(target) => write!(f, "jmp {target}"),
Self::WAIT => write!(f, "WAIT"),
Self::PUSHF => write!(f, "PUSHF"),
Self::POPF => write!(f, "POPF"),
Self::SAHF => write!(f, "SAHF"),
Self::LAHF => write!(f, "LAHF"),
Self::MOVSB => write!(f, "MOVSB"),
Self::MOVSW => write!(f, "MOVSW"),
Self::CMPSB => write!(f, "CMPSB"),
Self::CMPSW => write!(f, "CMPSW"),
Self::STOSB => write!(f, "STOSB"),
Self::STOSW => write!(f, "STOSW"),
Self::LODSB => write!(f, "LODSB"),
Self::LODSW => write!(f, "LODSW"),
Self::SCASB => write!(f, "SCASB"),
Self::SCASW => write!(f, "SCASW"),
Self::RET_Iw(word) => write!(f, "ret {word:#04x}"),
Self::RET => write!(f, "ret"),
Self::RETF_Iw(word) => write!(f, "retf {word:#04x}"),
Self::RETF => write!(f, "retf"),
Self::IRET => write!(f, "iret"),
Self::LES(target) => write!(f, "les {target}"),
Self::LDS(target) => write!(f, "lds {target}"),
Self::NOT(target) => write!(f, "not {target}"),
Self::NEG(target) => write!(f, "neg {target}"),
Self::MUL(target) => write!(f, "mul {target}"),
Self::IMUL(target) => write!(f, "imul {target}"),
Self::DIV(target) => write!(f, "mdiv {target}"),
Self::IDIV(target) => write!(f, "idiv {target}"),
Self::HLT => write!(f, "HLT"),
Self::ROL_b(target, byte) => write!(f, "rol {target}, {byte:#04x}"),
Self::ROR_b(target, byte) => write!(f, "ror {target}, {byte:#04x}"),
Self::RCL_b(target, byte) => write!(f, "rcl {target}, {byte:#04x}"),
Self::RCR_b(target, byte) => write!(f, "rcr {target}, {byte:#04x}"),
Self::SHL_b(target, byte) => write!(f, "shl {target}, {byte:#04x}"),
Self::SHR_b(target, byte) => write!(f, "shr {target}, {byte:#04x}"),
Self::SAR_b(target, byte) => write!(f, "sar {target}, {byte:#04x}"),
Self::ROL_fromReg(target, reg) => write!(f, "rol {target}, {reg}"),
Self::ROR_fromReg(target, reg) => write!(f, "ror {target}, {reg}"),
Self::RCL_fromReg(target, reg) => write!(f, "rcl {target}, {reg}"),
Self::RCR_fromReg(target, reg) => write!(f, "rcr {target}, {reg}"),
Self::SHL_fromReg(target, reg) => write!(f, "shl {target}, {reg}"),
Self::SHR_fromReg(target, reg) => write!(f, "shr {target}, {reg}"),
Self::SAR_fromReg(target, reg) => write!(f, "sar {target}, {reg}"),
Self::IN_AL(byte) => write!(f, "in {}, {byte:#04x}", Register::AL),
Self::IN_AX(byte) => write!(f, "in {}, {byte:#04x}", Register::AX),
Self::IN_ALDX => write!(f, "in {}, {}", Register::AL, Register::DX),
Self::IN_AXDX => write!(f, "in {}, {}", Register::AX, Register::DX),
Self::OUT_AL(byte) => write!(f, "out {}, {byte:#04x}", Register::AL),
Self::OUT_AX(byte) => write!(f, "out {}, {byte:#04x}", Register::AX),
Self::OUT_ALDX => write!(f, "out {}, {}", Register::AL, Register::DX),
Self::OUT_AXDX => write!(f, "out {}, {}", Register::AX, Register::DX),
Self::INT(byte) => write!(f, "int {byte:#04x}"),
Self::INTO => write!(f, "into"),
Self::CLC => write!(f, "clc"),
Self::STC => write!(f, "stc"),
Self::CLI => write!(f, "cli"),
Self::STI => write!(f, "sti"),
Self::CLD => write!(f, "cld"),
Self::STD => write!(f, "std"),
Self::CMC => write!(f, "cmc"),
Self::REPNZ => write!(f, "repnz"),
Self::REPZ => write!(f, "repz"),
Self::AAM(byte) => write!(f, "aam {byte:#04x}"),
Self::AAD(byte) => write!(f, "aad {byte:#04x}"),
Self::XLAT => write!(f, "xlat"),
_ => write!(f, "??? ??, ??"),
}
}
@@ -357,7 +579,8 @@ impl std::fmt::Display for ModRmTarget {
}
#[derive(Debug, Clone)]
/// Displacements are signed versions of u8 and u16.
/// Memory displacements are signed versions of u8 and u16.
/// Encodes either Byte- or Word-sized operands.
pub enum Displacement {
IByte(i8),
IWord(i16),