fix: correctly parse jump bytes
Previously only a single byte was read and saved, but the J-byte means, that the read signed-byte must be added to the address of the next instruction.
This commit is contained in:
@@ -103,6 +103,26 @@ impl Disassembler {
|
|||||||
u16::from_le_bytes([byte1, byte2])
|
u16::from_le_bytes([byte1, byte2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a single byte of binary and advance the offset.
|
||||||
|
/// The returned IByte contains a relative offset to be added to the address
|
||||||
|
/// of the subsequent instruction.
|
||||||
|
pub fn parse_j_byte(&mut self) -> isize {
|
||||||
|
// first interpret as 2-complement, then cast for addition
|
||||||
|
let byte = self.parse_byte() as IByte as isize;
|
||||||
|
let next_addr = (self.offset + 1) as isize;
|
||||||
|
byte + next_addr
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a single byte of binary and advance the offset.
|
||||||
|
/// The returned IByte contains a relative offset to be added to the address
|
||||||
|
/// of the subsequent instruction.
|
||||||
|
pub fn parse_j_word(&mut self) -> isize {
|
||||||
|
// first interpret as 2-complement, then cast for addition
|
||||||
|
let word = self.parse_word() as IWord as isize;
|
||||||
|
let next_addr = (self.offset + 1) as isize;
|
||||||
|
word + next_addr
|
||||||
|
}
|
||||||
|
|
||||||
/// Takes in a modrm byte and returns mod, reg and r/m.
|
/// Takes in a modrm byte and returns mod, reg and r/m.
|
||||||
fn deconstruct_modrm_byte(modrm: u8) -> (u8, u8, u8) {
|
fn deconstruct_modrm_byte(modrm: u8) -> (u8, u8, u8) {
|
||||||
let mode = (modrm >> 6) & 0b11;
|
let mode = (modrm >> 6) & 0b11;
|
||||||
@@ -442,22 +462,22 @@ impl Disassembler {
|
|||||||
|
|
||||||
0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)),
|
0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)),
|
||||||
|
|
||||||
0x70 => Mnemonic::JO(self.parse_byte() as IByte),
|
0x70 => Mnemonic::JO(self.parse_j_byte()),
|
||||||
0x71 => Mnemonic::JNO(self.parse_byte() as IByte),
|
0x71 => Mnemonic::JNO(self.parse_j_byte()),
|
||||||
0x72 => Mnemonic::JB(self.parse_byte() as IByte),
|
0x72 => Mnemonic::JB(self.parse_j_byte()),
|
||||||
0x73 => Mnemonic::JNB(self.parse_byte() as IByte),
|
0x73 => Mnemonic::JNB(self.parse_j_byte()),
|
||||||
0x74 => Mnemonic::JZ(self.parse_byte() as IByte),
|
0x74 => Mnemonic::JZ(self.parse_j_byte()),
|
||||||
0x75 => Mnemonic::JNZ(self.parse_byte() as IByte),
|
0x75 => Mnemonic::JNZ(self.parse_j_byte()),
|
||||||
0x76 => Mnemonic::JBE(self.parse_byte() as IByte),
|
0x76 => Mnemonic::JBE(self.parse_j_byte()),
|
||||||
0x77 => Mnemonic::JA(self.parse_byte() as IByte),
|
0x77 => Mnemonic::JA(self.parse_j_byte()),
|
||||||
0x78 => Mnemonic::JS(self.parse_byte() as IByte),
|
0x78 => Mnemonic::JS(self.parse_j_byte()),
|
||||||
0x79 => Mnemonic::JNS(self.parse_byte() as IByte),
|
0x79 => Mnemonic::JNS(self.parse_j_byte()),
|
||||||
0x7A => Mnemonic::JPE(self.parse_byte() as IByte),
|
0x7A => Mnemonic::JPE(self.parse_j_byte()),
|
||||||
0x7B => Mnemonic::JPO(self.parse_byte() as IByte),
|
0x7B => Mnemonic::JPO(self.parse_j_byte()),
|
||||||
0x7C => Mnemonic::JL(self.parse_byte() as IByte),
|
0x7C => Mnemonic::JL(self.parse_j_byte()),
|
||||||
0x7D => Mnemonic::JGE(self.parse_byte() as IByte),
|
0x7D => Mnemonic::JGE(self.parse_j_byte()),
|
||||||
0x7E => Mnemonic::JLE(self.parse_byte() as IByte),
|
0x7E => Mnemonic::JLE(self.parse_j_byte()),
|
||||||
0x7F => Mnemonic::JG(self.parse_byte() as IByte),
|
0x7F => Mnemonic::JG(self.parse_j_byte()),
|
||||||
|
|
||||||
// Group 1
|
// Group 1
|
||||||
0x80 => {
|
0x80 => {
|
||||||
@@ -622,36 +642,24 @@ impl Disassembler {
|
|||||||
|
|
||||||
0xD8..=0xDF => return Err(DisasmError::OpcodeUndefined(opcode)),
|
0xD8..=0xDF => return Err(DisasmError::OpcodeUndefined(opcode)),
|
||||||
|
|
||||||
0xE0 => Mnemonic::LOOPNZ(self.parse_byte() as IByte),
|
0xE0 => Mnemonic::LOOPNZ(self.parse_j_byte()),
|
||||||
0xE1 => Mnemonic::LOOPZ(self.parse_byte() as IByte),
|
0xE1 => Mnemonic::LOOPZ(self.parse_j_byte()),
|
||||||
0xE2 => Mnemonic::LOOP(self.parse_byte() as IByte),
|
0xE2 => Mnemonic::LOOP(self.parse_j_byte()),
|
||||||
0xE3 => Mnemonic::JCXZ(self.parse_byte() as IByte),
|
0xE3 => Mnemonic::JCXZ(self.parse_j_byte()),
|
||||||
|
|
||||||
0xE4 => Mnemonic::IN_AL(self.parse_byte()),
|
0xE4 => Mnemonic::IN_AL(self.parse_byte()),
|
||||||
0xE5 => Mnemonic::IN_AX(self.parse_byte()),
|
0xE5 => Mnemonic::IN_AX(self.parse_byte()),
|
||||||
0xE6 => Mnemonic::OUT_AL(self.parse_byte()),
|
0xE6 => Mnemonic::OUT_AL(self.parse_byte()),
|
||||||
0xE7 => Mnemonic::OUT_AX(self.parse_byte()),
|
0xE7 => Mnemonic::OUT_AX(self.parse_byte()),
|
||||||
|
|
||||||
0xE8 => Mnemonic::CALL_v(self.parse_word()),
|
0xE8 => Mnemonic::CALL_v(self.parse_j_word()),
|
||||||
|
|
||||||
// add to address of next instruction
|
0xE9 => Mnemonic::JMP_v(self.parse_j_word()),
|
||||||
0xE9 => {
|
|
||||||
// first interpret as IByte, then cast for addition
|
|
||||||
let word = self.parse_word() as IByte as isize;
|
|
||||||
let next_addr = (self.offset + 1) as isize;
|
|
||||||
Mnemonic::JMP_v(next_addr + word)
|
|
||||||
}
|
|
||||||
0xEA => Mnemonic::JMP_p(Pointer {
|
0xEA => Mnemonic::JMP_p(Pointer {
|
||||||
segment: self.parse_word(),
|
segment: self.parse_word(),
|
||||||
offset: self.parse_word(),
|
offset: self.parse_word(),
|
||||||
}),
|
}),
|
||||||
// add to address of next instruction
|
0xEB => Mnemonic::JMP_b(self.parse_j_byte()),
|
||||||
0xEB => {
|
|
||||||
// first interpret as IByte, then cast for addition
|
|
||||||
let byte = self.parse_byte() as IByte as isize;
|
|
||||||
let next_addr = (self.offset + 1) as isize;
|
|
||||||
Mnemonic::JMP_b(next_addr + byte)
|
|
||||||
}
|
|
||||||
|
|
||||||
0xEC => Mnemonic::IN_ALDX,
|
0xEC => Mnemonic::IN_ALDX,
|
||||||
0xED => Mnemonic::IN_AXDX,
|
0xED => Mnemonic::IN_AXDX,
|
||||||
|
|||||||
@@ -165,26 +165,26 @@ pub enum Mnemonic {
|
|||||||
DEC_Reg(Register),
|
DEC_Reg(Register),
|
||||||
DEC_Mod(ModRmTarget),
|
DEC_Mod(ModRmTarget),
|
||||||
// Jumps
|
// Jumps
|
||||||
JO(IByte),
|
JO(isize),
|
||||||
JNO(IByte),
|
JNO(isize),
|
||||||
JB(IByte),
|
JB(isize),
|
||||||
JNB(IByte),
|
JNB(isize),
|
||||||
JZ(IByte),
|
JZ(isize),
|
||||||
JNZ(IByte),
|
JNZ(isize),
|
||||||
JBE(IByte),
|
JBE(isize),
|
||||||
JA(IByte),
|
JA(isize),
|
||||||
JS(IByte),
|
JS(isize),
|
||||||
JNS(IByte),
|
JNS(isize),
|
||||||
JPE(IByte),
|
JPE(isize),
|
||||||
JPO(IByte),
|
JPO(isize),
|
||||||
JL(IByte),
|
JL(isize),
|
||||||
JGE(IByte),
|
JGE(isize),
|
||||||
JLE(IByte),
|
JLE(isize),
|
||||||
JG(IByte),
|
JG(isize),
|
||||||
LOOPNZ(IByte),
|
LOOPNZ(isize),
|
||||||
LOOPZ(IByte),
|
LOOPZ(isize),
|
||||||
LOOP(IByte),
|
LOOP(isize),
|
||||||
JCXZ(IByte),
|
JCXZ(isize),
|
||||||
|
|
||||||
// TEST
|
// TEST
|
||||||
TEST(ModRmTarget, Register),
|
TEST(ModRmTarget, Register),
|
||||||
@@ -231,7 +231,7 @@ pub enum Mnemonic {
|
|||||||
CWD,
|
CWD,
|
||||||
// CALL
|
// CALL
|
||||||
CALL_p(Pointer),
|
CALL_p(Pointer),
|
||||||
CALL_v(Word),
|
CALL_v(isize),
|
||||||
CALL_Mod(ModRmTarget),
|
CALL_Mod(ModRmTarget),
|
||||||
// JUMP
|
// JUMP
|
||||||
JMP_p(Pointer),
|
JMP_p(Pointer),
|
||||||
|
|||||||
Reference in New Issue
Block a user