aboutsummaryrefslogtreecommitdiff
path: root/src/long_mode
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-08-21 19:58:19 -0700
committeriximeow <me@iximeow.net>2021-08-21 19:58:19 -0700
commit1c06541a85fadbc5b9fc0a3bfee10cec3c8e5667 (patch)
tree68adb5ba8768a461ee725f7b42fd1b6211df6822 /src/long_mode
parenta5a67ee666381b2716862dec6df2e85419c352bc (diff)
improve relative branch offset formatting for DisplayStyle::C
Diffstat (limited to 'src/long_mode')
-rw-r--r--src/long_mode/display.rs107
1 files changed, 104 insertions, 3 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index 7bbd83f..181217c 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -3463,7 +3463,7 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:
Ok(())
}
-fn contextualize_c<T: fmt::Write, Y: YaxColors>(instr: &Instruction, _colors: &Y, _address: u64, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
+fn contextualize_c<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: &Y, _address: u64, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
let mut brace_count = 0;
let mut prefixed = false;
@@ -3509,6 +3509,26 @@ fn contextualize_c<T: fmt::Write, Y: YaxColors>(instr: &Instruction, _colors: &Y
}
}
+ fn write_jmp_operand<T: fmt::Write, Y: YaxColors>(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 => {
@@ -3662,9 +3682,90 @@ fn contextualize_c<T: fmt::Write, Y: YaxColors>(instr: &Instruction, _colors: &Y
write!(out, "{}--", instr.operand(0))?;
}
}
+ Opcode::JMP => {
+ out.write_str("jmp ")?;
+ write_jmp_operand(instr.operand(0), colors, out)?;
+ },
+ Opcode::JRCXZ => {
+ out.write_str("if rcx == 0 then jmp ")?;
+ write_jmp_operand(instr.operand(0), colors, out)?;
+ },
+ Opcode::LOOP => {
+ out.write_str("rcx--; if rcx != 0 then jmp ")?;
+ write_jmp_operand(instr.operand(0), colors, out)?;
+ },
+ Opcode::LOOPZ => {
+ out.write_str("rcx--; if rcx != 0 and zero(rflags) then jmp ")?;
+ write_jmp_operand(instr.operand(0), colors, out)?;
+ },
+ Opcode::LOOPNZ => {
+ out.write_str("rcx--; if rcx != 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(rflags) 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")?;
}