Search code examples
assemblyx86callinstructionsmachine-code

How does the layout of a indirect/direct call instruction look like in memory?


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.


Solution

  • 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