diff --git a/src/disasm.rs b/src/disasm.rs index 5fc7e44..a8583aa 100644 --- a/src/disasm.rs +++ b/src/disasm.rs @@ -103,6 +103,26 @@ impl Disassembler { 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. fn deconstruct_modrm_byte(modrm: u8) -> (u8, u8, u8) { let mode = (modrm >> 6) & 0b11; @@ -442,22 +462,22 @@ impl Disassembler { 0x60..=0x6F => return Err(DisasmError::OpcodeUndefined(opcode)), - 0x70 => Mnemonic::JO(self.parse_byte() as IByte), - 0x71 => Mnemonic::JNO(self.parse_byte() as IByte), - 0x72 => Mnemonic::JB(self.parse_byte() as IByte), - 0x73 => Mnemonic::JNB(self.parse_byte() as IByte), - 0x74 => Mnemonic::JZ(self.parse_byte() as IByte), - 0x75 => Mnemonic::JNZ(self.parse_byte() as IByte), - 0x76 => Mnemonic::JBE(self.parse_byte() as IByte), - 0x77 => Mnemonic::JA(self.parse_byte() as IByte), - 0x78 => Mnemonic::JS(self.parse_byte() as IByte), - 0x79 => Mnemonic::JNS(self.parse_byte() as IByte), - 0x7A => Mnemonic::JPE(self.parse_byte() as IByte), - 0x7B => Mnemonic::JPO(self.parse_byte() as IByte), - 0x7C => Mnemonic::JL(self.parse_byte() as IByte), - 0x7D => Mnemonic::JGE(self.parse_byte() as IByte), - 0x7E => Mnemonic::JLE(self.parse_byte() as IByte), - 0x7F => Mnemonic::JG(self.parse_byte() as IByte), + 0x70 => Mnemonic::JO(self.parse_j_byte()), + 0x71 => Mnemonic::JNO(self.parse_j_byte()), + 0x72 => Mnemonic::JB(self.parse_j_byte()), + 0x73 => Mnemonic::JNB(self.parse_j_byte()), + 0x74 => Mnemonic::JZ(self.parse_j_byte()), + 0x75 => Mnemonic::JNZ(self.parse_j_byte()), + 0x76 => Mnemonic::JBE(self.parse_j_byte()), + 0x77 => Mnemonic::JA(self.parse_j_byte()), + 0x78 => Mnemonic::JS(self.parse_j_byte()), + 0x79 => Mnemonic::JNS(self.parse_j_byte()), + 0x7A => Mnemonic::JPE(self.parse_j_byte()), + 0x7B => Mnemonic::JPO(self.parse_j_byte()), + 0x7C => Mnemonic::JL(self.parse_j_byte()), + 0x7D => Mnemonic::JGE(self.parse_j_byte()), + 0x7E => Mnemonic::JLE(self.parse_j_byte()), + 0x7F => Mnemonic::JG(self.parse_j_byte()), // Group 1 0x80 => { @@ -622,36 +642,24 @@ impl Disassembler { 0xD8..=0xDF => return Err(DisasmError::OpcodeUndefined(opcode)), - 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), + 0xE0 => Mnemonic::LOOPNZ(self.parse_j_byte()), + 0xE1 => Mnemonic::LOOPZ(self.parse_j_byte()), + 0xE2 => Mnemonic::LOOP(self.parse_j_byte()), + 0xE3 => Mnemonic::JCXZ(self.parse_j_byte()), 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_j_word()), - // add to address of next instruction - 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) - } + 0xE9 => Mnemonic::JMP_v(self.parse_j_word()), 0xEA => Mnemonic::JMP_p(Pointer { segment: self.parse_word(), offset: self.parse_word(), }), - // add to address of next instruction - 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) - } + 0xEB => Mnemonic::JMP_b(self.parse_j_byte()), 0xEC => Mnemonic::IN_ALDX, 0xED => Mnemonic::IN_AXDX, diff --git a/src/instructions.rs b/src/instructions.rs index 0ac2cad..6bedb60 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -165,26 +165,26 @@ pub enum Mnemonic { DEC_Reg(Register), DEC_Mod(ModRmTarget), // Jumps - JO(IByte), - JNO(IByte), - JB(IByte), - JNB(IByte), - JZ(IByte), - JNZ(IByte), - JBE(IByte), - JA(IByte), - JS(IByte), - JNS(IByte), - JPE(IByte), - JPO(IByte), - JL(IByte), - JGE(IByte), - JLE(IByte), - JG(IByte), - LOOPNZ(IByte), - LOOPZ(IByte), - LOOP(IByte), - JCXZ(IByte), + JO(isize), + JNO(isize), + JB(isize), + JNB(isize), + JZ(isize), + JNZ(isize), + JBE(isize), + JA(isize), + JS(isize), + JNS(isize), + JPE(isize), + JPO(isize), + JL(isize), + JGE(isize), + JLE(isize), + JG(isize), + LOOPNZ(isize), + LOOPZ(isize), + LOOP(isize), + JCXZ(isize), // TEST TEST(ModRmTarget, Register), @@ -231,7 +231,7 @@ pub enum Mnemonic { CWD, // CALL CALL_p(Pointer), - CALL_v(Word), + CALL_v(isize), CALL_Mod(ModRmTarget), // JUMP JMP_p(Pointer),