diff options
-rw-r--r-- | src/long_mode/display.rs | 28 | ||||
-rw-r--r-- | src/protected_mode/display.rs | 28 | ||||
-rw-r--r-- | src/real_mode/display.rs | 28 | ||||
-rw-r--r-- | test/long_mode/mod.rs | 17 | ||||
-rw-r--r-- | test/protected_mode/mod.rs | 17 | ||||
-rw-r--r-- | test/real_mode/mod.rs | 17 |
6 files changed, 111 insertions, 24 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 68189f0..59efe38 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -3338,6 +3338,34 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: out.write_str(" ")?; let x = Operand::from_spec(instr, instr.operands[0]); + + const RELATIVE_BRANCHES: [Opcode; 21] = [ + Opcode::JMP, Opcode::JRCXZ, + Opcode::LOOP, Opcode::LOOPZ, Opcode::LOOPNZ, + Opcode::JO, Opcode::JNO, + Opcode::JB, Opcode::JNB, + Opcode::JZ, Opcode::JNZ, + Opcode::JNA, Opcode::JA, + Opcode::JS, Opcode::JNS, + Opcode::JP, Opcode::JNP, + Opcode::JL, Opcode::JGE, + Opcode::JLE, Opcode::JG, + ]; + + if instr.operands[0] == OperandSpec::ImmI8 || instr.operands[0] == OperandSpec::ImmI32 { + if RELATIVE_BRANCHES.contains(&instr.opcode) { + return match x { + Operand::ImmediateI8(rel) => { + write!(out, "$+{}", colors.number(signed_i32_hex(rel as i32))) + } + Operand::ImmediateI32(rel) => { + write!(out, "$+{}", colors.number(signed_i32_hex(rel))) + } + _ => { unreachable!() } + }; + } + } + if x.is_memory() { out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?; out.write_str(" ")?; diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs index 987221e..72bfcb4 100644 --- a/src/protected_mode/display.rs +++ b/src/protected_mode/display.rs @@ -3351,6 +3351,34 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: out.write_str(" ")?; let x = Operand::from_spec(instr, instr.operands[0]); + + const RELATIVE_BRANCHES: [Opcode; 21] = [ + Opcode::JMP, Opcode::JECXZ, + Opcode::LOOP, Opcode::LOOPZ, Opcode::LOOPNZ, + Opcode::JO, Opcode::JNO, + Opcode::JB, Opcode::JNB, + Opcode::JZ, Opcode::JNZ, + Opcode::JNA, Opcode::JA, + Opcode::JS, Opcode::JNS, + Opcode::JP, Opcode::JNP, + Opcode::JL, Opcode::JGE, + Opcode::JLE, Opcode::JG, + ]; + + if instr.operands[0] == OperandSpec::ImmI8 || instr.operands[0] == OperandSpec::ImmI32 { + if RELATIVE_BRANCHES.contains(&instr.opcode) { + return match x { + Operand::ImmediateI8(rel) => { + write!(out, "$+{}", colors.number(signed_i32_hex(rel as i32))) + } + Operand::ImmediateI32(rel) => { + write!(out, "$+{}", colors.number(signed_i32_hex(rel))) + } + _ => { unreachable!() } + }; + } + } + if x.is_memory() { out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?; out.write_str(" ")?; diff --git a/src/real_mode/display.rs b/src/real_mode/display.rs index 9ba8284..f514974 100644 --- a/src/real_mode/display.rs +++ b/src/real_mode/display.rs @@ -3351,6 +3351,34 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: out.write_str(" ")?; let x = Operand::from_spec(instr, instr.operands[0]); + + const RELATIVE_BRANCHES: [Opcode; 21] = [ + Opcode::JMP, Opcode::JCXZ, + Opcode::LOOP, Opcode::LOOPZ, Opcode::LOOPNZ, + Opcode::JO, Opcode::JNO, + Opcode::JB, Opcode::JNB, + Opcode::JZ, Opcode::JNZ, + Opcode::JNA, Opcode::JA, + Opcode::JS, Opcode::JNS, + Opcode::JP, Opcode::JNP, + Opcode::JL, Opcode::JGE, + Opcode::JLE, Opcode::JG, + ]; + + if instr.operands[0] == OperandSpec::ImmI8 || instr.operands[0] == OperandSpec::ImmI32 { + if RELATIVE_BRANCHES.contains(&instr.opcode) { + return match x { + Operand::ImmediateI8(rel) => { + write!(out, "$+{}", colors.number(signed_i32_hex(rel as i32))) + } + Operand::ImmediateI32(rel) => { + write!(out, "$+{}", colors.number(signed_i32_hex(rel))) + } + _ => { unreachable!() } + }; + } + } + if x.is_memory() { out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?; out.write_str(" ")?; diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index bfe21bd..61ea63d 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -1208,10 +1208,10 @@ fn test_prefixes() { #[test] fn test_control_flow() { - test_display(&[0x73, 0x31], "jnb 0x31"); - test_display(&[0x72, 0x5a], "jb 0x5a"); - test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna 0x18b"); - test_display(&[0x74, 0x47], "jz 0x47"); + test_display(&[0x73, 0x31], "jnb $+0x31"); + test_display(&[0x72, 0x5a], "jb $+0x5a"); + test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna $+0x18b"); + test_display(&[0x74, 0x47], "jz $+0x47"); test_display(&[0xff, 0x15, 0x7e, 0x72, 0x24, 0x00], "call qword [rip + 0x24727e]"); test_display(&[0xff, 0x24, 0xcd, 0x70, 0xa0, 0xbc, 0x01], "jmp qword [rcx * 8 + 0x1bca070]"); test_display(&[0xff, 0xe0], "jmp rax"); @@ -1219,10 +1219,11 @@ fn test_control_flow() { test_display(&[0x67, 0xff, 0xe0], "jmp rax"); test_invalid(&[0xff, 0xd8]); test_display(&[0xff, 0x18], "callf mword [rax]"); - test_display(&[0xe0, 0x12], "loopnz 0x12"); - test_display(&[0xe1, 0x12], "loopz 0x12"); - test_display(&[0xe2, 0x12], "loop 0x12"); - test_display(&[0xe3, 0x12], "jrcxz 0x12"); + test_display(&[0xe0, 0x12], "loopnz $+0x12"); + test_display(&[0xe1, 0x12], "loopz $+0x12"); + test_display(&[0xe2, 0x12], "loop $+0x12"); + test_display(&[0xe3, 0x12], "jrcxz $+0x12"); + test_display(&[0xe3, 0xf0], "jrcxz $+-0x10"); test_display(&[0xc3], "ret"); } diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index c03a19d..5ed69ed 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -1094,10 +1094,10 @@ fn test_prefixes() { #[test] fn test_control_flow() { - test_display(&[0x73, 0x31], "jnb 0x31"); - test_display(&[0x72, 0x5a], "jb 0x5a"); - test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna 0x18b"); - test_display(&[0x74, 0x47], "jz 0x47"); + test_display(&[0x73, 0x31], "jnb $+0x31"); + test_display(&[0x72, 0x5a], "jb $+0x5a"); + test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna $+0x18b"); + test_display(&[0x74, 0x47], "jz $+0x47"); test_display(&[0xff, 0x15, 0x7e, 0x72, 0x24, 0x00], "call dword [0x24727e]"); test_display(&[0xff, 0x24, 0xcd, 0x70, 0xa0, 0xbc, 0x01], "jmp dword [ecx * 8 + 0x1bca070]"); test_display(&[0xff, 0xe0], "jmp eax"); @@ -1105,10 +1105,11 @@ fn test_control_flow() { test_display(&[0x67, 0xff, 0xe0], "jmp eax"); test_invalid(&[0xff, 0xd8]); test_display(&[0xff, 0x18], "callf far [eax]"); - test_display(&[0xe0, 0x12], "loopnz 0x12"); - test_display(&[0xe1, 0x12], "loopz 0x12"); - test_display(&[0xe2, 0x12], "loop 0x12"); - test_display(&[0xe3, 0x12], "jecxz 0x12"); + test_display(&[0xe0, 0x12], "loopnz $+0x12"); + test_display(&[0xe1, 0x12], "loopz $+0x12"); + test_display(&[0xe2, 0x12], "loop $+0x12"); + test_display(&[0xe3, 0x12], "jecxz $+0x12"); + test_display(&[0xe3, 0xf0], "jecxz $+-0x10"); test_display(&[0xc3], "ret"); } diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs index 82ccfab..6005f07 100644 --- a/test/real_mode/mod.rs +++ b/test/real_mode/mod.rs @@ -262,7 +262,7 @@ fn test_real_mode() { test_display(&[0x0f, 0x7e, 0xcf], "movd edi, mm1"); test_display(&[0x0f, 0x7f, 0x0f], "movq qword [bx], mm1"); test_display(&[0x0f, 0x7f, 0xcf], "movq mm7, mm1"); - test_display(&[0x0f, 0x86, 0x8b, 0x01], "jna 0x18b"); + test_display(&[0x0f, 0x86, 0x8b, 0x01], "jna $+0x18b"); test_display(&[0x0f, 0x97, 0x00], "seta byte [bx + si]"); test_display(&[0x0f, 0x97, 0x08], "seta byte [bx + si]"); test_display(&[0x0f, 0x97, 0xc0], "seta al"); @@ -16924,9 +16924,9 @@ fn test_real_mode() { test_display(&[0x67, 0xff, 0xe0], "jmp ax"); test_display(&[0x68, 0x7f, 0x63], "push 0x637f"); test_display(&[0x6b, 0x43, 0x6f, 0x6d], "imul ax, word [bp + di + 0x6f], 0x6d"); - test_display(&[0x72, 0x5a], "jb 0x5a"); - test_display(&[0x73, 0x31], "jnb 0x31"); - test_display(&[0x74, 0x47], "jz 0x47"); + test_display(&[0x72, 0x5a], "jb $+0x5a"); + test_display(&[0x73, 0x31], "jnb $+0x31"); + test_display(&[0x74, 0x47], "jz $+0x47"); test_display(&[0x81, 0xec, 0x10, 0x03], "sub sp, 0x310"); test_display(&[0x66, 0x81, 0xec, 0x10, 0x03, 0x00, 0x00], "sub esp, 0x310"); test_display(&[0x83, 0xf8, 0xff], "cmp ax, -0x1"); @@ -17752,10 +17752,11 @@ fn test_real_mode() { test_display(&[0xdf, 0xe0], "fnstsw ax"); test_display(&[0xdf, 0xeb], "fucomip st(0), st(3)"); test_display(&[0xdf, 0xf3], "fcomip st(0), st(3)"); - test_display(&[0xe0, 0x12], "loopnz 0x12"); - test_display(&[0xe1, 0x12], "loopz 0x12"); - test_display(&[0xe2, 0x12], "loop 0x12"); - test_display(&[0xe3, 0x12], "jcxz 0x12"); + test_display(&[0xe0, 0x12], "loopnz $+0x12"); + test_display(&[0xe1, 0x12], "loopz $+0x12"); + test_display(&[0xe2, 0x12], "loop $+0x12"); + test_display(&[0xe3, 0x12], "jcxz $+0x12"); + test_display(&[0xe3, 0xf0], "jcxz $+-0x10"); test_display(&[0xe4, 0x99], "in al, 0x99"); test_display(&[0xe5, 0x99], "in ax, 0x99"); test_display(&[0xe6, 0x99], "out 0x99, al"); |