There are several cases where a branch is performed on register's content (or variable content, for that matter)
- Jump table for switches, where the address to jump to is calculated using some table of addresses/offsets and the value of a register.
- A function pointer, such as callback function, where the function to be called is given as a parameter to the caller, or stored in some variable.
- virtual function tables in C++, where the function to be called is not known at compile time, and may change in runtime.
Here is an example for function pointer call (64 bit Mac OS):
C code
int fptr_call( int (*ptr)(int) ) {
return (*ptr)( 3 );
}
Assembly
_fptr_call:
0000000100000e70 pushq %rbp
0000000100000e71 movq %rsp, %rbp
0000000100000e74 subq $0x10, %rsp
0000000100000e78 movl $0x3, %eax
0000000100000e7d movq %rdi, 0xfffffffffffffff8(%rbp)
0000000100000e81 movl %eax, %edi
; Call based on %rbp, copied from %rdi which is ptr
0000000100000e83 callq *0xfffffffffffffff8(%rbp)
0000000100000e86 addq $0x10, %rsp
0000000100000e8a popq %rbp
0000000100000e8b ret
0000000100000e8c nopl (%rax)