I'm comparing indirect call instruction against direct call instruction, and I want to know the layout( of them in memory, espically in x86 platform.
Many thanks.
A direct call looks like a call to the adress of the fucntion (the address is hardwritten in the code section here at the relative address ff ff ff b5 means -46 [the function actually is located 0x46 bytes before the call instruction])
6d0: e8 b5 ff ff ff callq 68a <subroutine>
While an indirect call looks like a call eax (the address is in a register : here rax)
6e4: ff d0 callq *%rax
An example main.c
#include <stdio.h>
typedef int (*func_t)(void);
int subroutine(){
printf(" I am the subroutine\n");
return 0;
}
int main(int argc, char *argv[])
{
printf("--> Start %s\n", argv[0]);
// Direct call
subroutine();
// Indirect call
func_t f_sub = &subroutine;
f_sub();
return 0;
}
Compile and execute : gcc main.c -o main && ./main
Disassemble : objdump -d main
And here is the disassembled opcodes
00000000000006a1 <main>:
6a1: 55 push %rbp
6a2: 48 89 e5 mov %rsp,%rbp
6a5: 48 83 ec 20 sub $0x20,%rsp
6a9: 89 7d ec mov %edi,-0x14(%rbp)
6ac: 48 89 75 e0 mov %rsi,-0x20(%rbp)
6b0: 48 8b 45 e0 mov -0x20(%rbp),%rax
6b4: 48 8b 00 mov (%rax),%rax
6b7: 48 89 c6 mov %rax,%rsi
6ba: 48 8d 3d e9 00 00 00 lea 0xe9(%rip),%rdi # 7aa <_IO_stdin_used+0x1a>
6c1: b8 00 00 00 00 mov $0x0,%eax
6c6: e8 95 fe ff ff callq 560 <printf@plt>
6cb: b8 00 00 00 00 mov $0x0,%eax
6d0: e8 b5 ff ff ff callq 68a <subroutine>
6d5: 48 8d 05 ae ff ff ff lea -0x52(%rip),%rax # 68a <subroutine>
6dc: 48 89 45 f8 mov %rax,-0x8(%rbp)
6e0: 48 8b 45 f8 mov -0x8(%rbp),%rax
6e4: ff d0 callq *%rax
6e6: b8 00 00 00 00 mov $0x0,%eax
6eb: c9 leaveq
6ec: c3 retq