ft: implement some more instructions
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user