From 1c06541a85fadbc5b9fc0a3bfee10cec3c8e5667 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 21 Aug 2021 19:58:19 -0700 Subject: improve relative branch offset formatting for DisplayStyle::C --- src/protected_mode/display.rs | 107 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 3 deletions(-) (limited to 'src/protected_mode') diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs index 33c0cda..dac3684 100644 --- a/src/protected_mode/display.rs +++ b/src/protected_mode/display.rs @@ -3476,7 +3476,7 @@ fn contextualize_intel(instr: &Instruction, colors: Ok(()) } -fn contextualize_c(instr: &Instruction, _colors: &Y, _address: u32, _context: Option<&NoContext>, out: &mut T) -> fmt::Result { +fn contextualize_c(instr: &Instruction, colors: &Y, _address: u32, _context: Option<&NoContext>, out: &mut T) -> fmt::Result { let mut brace_count = 0; let mut prefixed = false; @@ -3522,6 +3522,26 @@ fn contextualize_c(instr: &Instruction, _colors: &Y } } + fn write_jmp_operand(op: Operand, colors: &Y, out: &mut T) -> fmt::Result { + match op { + Operand::ImmediateI8(rel) => { + if rel >= 0 { + write!(out, "$+{}", colors.number(signed_i32_hex(rel as i32))) + } else { + write!(out, "${}", colors.number(signed_i32_hex(rel as i32))) + } + } + Operand::ImmediateI32(rel) => { + if rel >= 0 { + write!(out, "$+{}", colors.number(signed_i32_hex(rel))) + } else { + write!(out, "${}", colors.number(signed_i32_hex(rel))) + } + } + _ => { unreachable!() } + } + } + match instr.opcode { Opcode::Invalid => { out.write_str("invalid")?; }, Opcode::MOVS => { @@ -3675,9 +3695,90 @@ fn contextualize_c(instr: &Instruction, _colors: &Y write!(out, "{}--", instr.operand(0))?; } } + Opcode::JMP => { + out.write_str("jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JECXZ => { + out.write_str("if ecx == 0 then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::LOOP => { + out.write_str("ecx--; if ecx != 0 then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::LOOPZ => { + out.write_str("ecx--; if ecx != 0 and zero(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::LOOPNZ => { + out.write_str("ecx--; if ecx != 0 and !zero(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JO => { + out.write_str("if _(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JNO => { + out.write_str("if _(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JB => { + out.write_str("if /* unsigned */ below(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JNB => { + out.write_str("if /* unsigned */ above_or_equal(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JZ => { + out.write_str("if zero(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JNZ => { + out.write_str("if !zero(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JNA => { + out.write_str("if /* unsigned */ below_or_equal(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JA => { + out.write_str("if /* unsigned */ above(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JS => { + out.write_str("if signed(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JNS => { + out.write_str("if !signed(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JP => { + out.write_str("if parity(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JNP => { + out.write_str("if !parity(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JL => { + out.write_str("if /* signed */ less(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JGE => { + out.write_str("if /* signed */ greater_or_equal(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, + Opcode::JLE => { + out.write_str("if /* signed */ less_or_equal(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, Opcode::JG => { - write!(out, "if greater(eflags) then jmp {}", instr.operand(0))?; - } + out.write_str("if /* signed */ greater(rflags) then jmp ")?; + write_jmp_operand(instr.operand(0), colors, out)?; + }, Opcode::NOP => { write!(out, "nop")?; } -- cgit v1.1