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.