How can I tell if jump is absolute or relative?
Asked Answered
I

3

6

I'm studying for a test in assembly and in the subject of "Position-Independent-Code" I find the difference between a relative jump and an absolute jump confusing. How can I tell what kind of jump it is?

I understand what a relative jump is (the offset from current line). But what does an absolute jump look like? When does it happen?

Incitement answered 21/7, 2015 at 15:59 Comment(1)
for architectures like x86 depending on the toolchain the only way to know is to disassemble the final binary, the linker can/will change the jump as it needs, even for arm and others the linker may modify the code there or add additional code to make a trampoline to have the overall effect of converting from whatever the compiler generated to what is needed. older linkers depending on architecture and toolchain would simply give an error instead, some still do, but gnu for example has started adding in more codeAssociate
A
9

Anything that looks like just plain jmp label is relative.

Absolute jumps look like

  • jmp register
  • jmp [address]
  • jmp segment:absoluteaddr
  • jmp far [address]

Any far jump is absolute, any indirect jump is absolute, the combination (far, indirect) is therefore also absolute. Far jump only happen when necessary (you have to change cs and it's not a call). Indirect jumps are used for function pointers, branch tables (used in some cases for switch statements), dynamic dispatch (virtual methods) and maybe for imported functions (usually you call them, but maybe it's a tail call).

Addam answered 21/7, 2015 at 17:2 Comment(0)
P
7

Depending on the architecture and on the assembler or mnemonics a relative jump may be not distinguishable from an absolute one.
Some architecture have different mnemonic (the name of the instruction encoded by some machine code) for each branch type, other have the same mnemonic.

Usually it is the assembler that take cares of writing the right jump instruction based on the distance of the target instruction.
Relative addressing is preferred because:

  • It allow us to create Position Independent Code, that is useful but only if we can also access data in a PIC fashion. In general on modern OS PIC is not a necessity.
    Infection vectors and shellcode instead take great advantage of PIC code, along with dinamically moved sections of code (for example Inter Process Interrupt with fixed vector on IA32 require a routine to be at a precise address).
  • It hugely reduce code size. Relative jumping may use an operand as little as 8 bit! This is extremely useful in system with wide address space in bits term.
  • Some machine have no choice, in RISC computers for example the instruction length is fixed, in ARM is 32 bit for non Thumb (and some Thumb) and you cannot code operation_field + 32bit_operand in 32 bit!

About the human factor, we usually are in the state "one way or another, it doesn't care" when programming so we let the assembler choose. Sometime when we write low level routines we may need to move them in memory and force the use of relative jumping. Sometime we want to jump to a fixed location (for example a reset vector at 0000h or 0ffff0h) wherever the code may end up in memory.


Some incomplete example of jumps

MIPS

beq, bne, bgtz, bgez, bltz, blez are all relative jumping

j, jal are kind of mixed, they are absolute but the high nibble of PC is kept.

jr, jalr are absolute (being indirect, i.e. using the value of a register).

For more info, see here.

ARM

b, bl, blx are relative.

bx, blx are absolute.

If you modify the PC directly it is an absolute jump.

Note how the instruction that take immediates are relative while the indirect one are not. This is very common in RISC.

For more info, see here.

IA32e

jmp this is either relative or absolute depending on the machine code used. More specifically jumps can be near or far. There is no near absolute direct jump. Absolute near jumps are always indirect (they use memory operand or register).
Far jump are always absolute and can be direct (the address is in the instruction operand) or indirect.

jmp label is a near jump relative.
jmp [dest], jmp eax are near absolute (indirect) jumps.
jmp 0ffff0:0000h is far absolute direct. jump FAR [dest] is far absolute indirect.

For more info you can see here.

Papen answered 21/7, 2015 at 17:42 Comment(1)
Trying to confuse the OP even more? With a tag like 8086 user lolu won't learn to much from your very high quality answer.Campinas
B
0

from what i recall, relative jump used when the code is positional independent (the code doesn't expect to be loaded into specific memory range. for instance dll library that is dynamically loaded). therefore, all branches in this code cannot assume they know the exact address to jump, but the relative offset between the branch IP and the target IP).

absolute jump get the exact address of the target, and it's used when the code have static address space.

hope it helps,

Beginning answered 21/7, 2015 at 16:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.