7

I am curious about the Difference between direct and indirect function() calls

Could anyone help in the diff analysis ?

The c source code could be found at subroutine_direct.c and subroutine_indirect.c

Note: the diff could be regenerated using command : objdump -drwC -Mintel subroutine_indirect

kevin
  • 187
  • 1
  • 1
  • 2

1 Answers1

11

The main difference between the direct and the indirect call, is that:

  • the direct call uses an instruction call with a fixed address as argument. After the linker has done its job, this address will be included in the opcode.
  • the indirect call uses an instruction call with a register as argument (here rax). The register is previously loaded either directly with the fixed address of the subroutine that is to be called, or with a value fetched from somewhere else, such as another register or a place in memory where the subroutine’s address was previously stored.

As a consequence, the direct call will always call the same subroutine, whereas the indirect call could call different subroutines, depending of what was loaded in the register before the call is made. Depending on the cpu, the indirect call might be a little slower since the indirection requires an extra effort.

A typical use case for the indirect call in assembly would be to implement what would be a call to a function pointer in C or a virtual member function in C++. In your example it’s the use of the function pointer f_sub in the C source code. The key take-away here is that the same code (use of function pointer in C or indirect call in assembler) could call any C function or assembly subroutine that has the same interface and the choice is made at runtime.

The other differences between the two files are cosmetic, except for the load of the subroutine’s address into rax.

Christophe
  • 74,672
  • 10
  • 115
  • 187
  • 1
    Indirect calls are also used for position independent code, where the address of a function in memory is only known when the program is loaded. So a direct call cannot be used without modifying the code which also has disadvantages. So when the app is loaded, function addresses are calculated and stored in memory. To call a function, read the address and then do an indirect call. – gnasher729 Nov 15 '19 at 20:21
  • 1
    @gnasher729 yes, this is a possibility. But, to be complete, we have as well the direct relative and the indirect relative call, which facilitate generation of [position independent code](https://en.m.wikipedia.org/wiki/Position-independent_code). Not to mention the relocation mechanism in the [OS loader](https://en.m.wikipedia.org/wiki/Portable_Executable). All this allows to use direct addressing despite changing load address. In asm here we clearly have an opcode e8xx for a direct call on one side and a ffxx for the indirect[call](https://c9x.me/x86/html/file_module_x86_id_26.html). – Christophe Nov 15 '19 at 21:53