ft: introduce modrm macro for leaner matching
All instructions which use a modrm instruction for memory reads from or into a register can make use of this macro
This commit is contained in:
@@ -2,7 +2,8 @@ use core::fmt;
|
||||
use std::{fs::File, io::Read, process::exit};
|
||||
|
||||
use crate::aout::Aout;
|
||||
use crate::instructions::{Displacement, MemoryIndex};
|
||||
use crate::instructions::{Displacement, MemoryIndex, RegisterId, SegmentRegister};
|
||||
use crate::modrm;
|
||||
use crate::{
|
||||
Args,
|
||||
instructions::{ImmediateByte, ImmediateWord, Instruction, Opcode, Register},
|
||||
@@ -99,7 +100,7 @@ impl Disassembler {
|
||||
|
||||
/// Parse a single modrm byte, return the resulting MemoryIndex and advance the offset.
|
||||
/// Returns the parsed modrm memory access and the source register
|
||||
pub fn parse_modrm_byte_to_memindex(&mut self) -> (MemoryIndex, Register) {
|
||||
pub fn parse_modrm_byte(&mut self) -> (MemoryIndex, RegisterId) {
|
||||
// advance to operand
|
||||
self.offset += 1;
|
||||
let modrm = self.text[self.offset];
|
||||
@@ -109,7 +110,7 @@ impl Disassembler {
|
||||
|
||||
// Calculate ModRM byte with bitmask
|
||||
let modulo = modrm >> 6;
|
||||
let reg = (modrm >> 3) & 7;
|
||||
let reg_id = (modrm >> 3) & 7;
|
||||
let rm = modrm & 7;
|
||||
|
||||
let displacement = match modulo {
|
||||
@@ -183,7 +184,7 @@ impl Disassembler {
|
||||
_ => panic!("Invalid ModRM byte encountered"),
|
||||
};
|
||||
|
||||
(index, Register::by_id(reg))
|
||||
(index, reg_id)
|
||||
}
|
||||
|
||||
/// Decode instructions from the text section of the provided binary
|
||||
@@ -205,14 +206,23 @@ impl Disassembler {
|
||||
self.instruction.raw.push(opcode);
|
||||
self.instruction.opcode = match opcode {
|
||||
// ADD
|
||||
0x00 => {
|
||||
let (idx, reg) = self.parse_modrm_byte_to_memindex();
|
||||
Opcode::ADD_EbGb(idx, reg)
|
||||
}
|
||||
0x00 => modrm!(self, ADD_EbGb),
|
||||
0x01 => modrm!(self, ADD_EvGv),
|
||||
0x02 => modrm!(self, ADD_GbEb),
|
||||
0x03 => modrm!(self, ADD_GvEv),
|
||||
0x04 => Opcode::ADD_ALIb(ImmediateByte(self.parse_byte())),
|
||||
0x05 => Opcode::ADD_AXIv(ImmediateWord(self.parse_word())),
|
||||
// PUSH
|
||||
0x06 => Opcode::PUSH(SegmentRegister::by_id(self.parse_modrm_byte().1)),
|
||||
// POP
|
||||
0x07 => Opcode::POP(SegmentRegister::by_id(self.parse_modrm_byte().1)),
|
||||
// OR
|
||||
0x08 => modrm!(self, OR_EbGb),
|
||||
0x0A => modrm!(self, OR_GbEb),
|
||||
// INT
|
||||
0xCD => Opcode::INT(ImmediateByte(self.parse_byte())),
|
||||
// MOV
|
||||
0xBB => Opcode::MOV_BXIv(Register::BX, ImmediateWord(self.parse_word())),
|
||||
0xBB => Opcode::MOV_BXIv(ImmediateWord(self.parse_word())),
|
||||
_ => {
|
||||
eprintln!(
|
||||
"Encountered unknown self.instructionuction '0x{:x}'",
|
||||
|
||||
Reference in New Issue
Block a user