1

I have the following C program to see how the main function is called with argc and argv as follows:

#include <stdio.h>

int main(int argc, char *argv[]) {
 // use a non-zero value so we can easily tell it ran properly with echo $?
    return 3;
}

And the non-optimized assembly output with $ gcc ifile.c -S -o ifile.s gives us:

    .file   "ifile.c"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6

    movl    %edi, -4(%rbp)  <== here
    movq    %rsi, -16(%rbp) <== here

    movl    $3, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
    .section    .note.GNU-stack,"",@progbits

I understand this with the exception of the two lines above preceding moving the return value into %eax:

    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)

What are these two lines doing? I am guessing the first line since it has an offset of 4 is populating the integer value of argc, and the second argument is passing an (8-byte) pointer padded to 16 for the strings that can be passed in the argv. Is this a correct understanding of these items? Where can I learn more about, not so much the full ABI, but the specific details/internals about how the main() function gets invoked and such?

David542
  • 104,438
  • 178
  • 489
  • 842
  • 1
    `main()` is invoked by the C runtime library, which gets argc/argv from the operating system and then just passes them as ordinary function arguments. – Barmar Sep 04 '20 at 05:15
  • @Barmar -- I see, so `%rdi` (`%edi` as the first arg only needs 4 bytes) and then `%rsi` and the first two args in the calling convention passed by the c runtime library? How can I view the c-runtime wrapping code to look into it a bit more? – David542 Sep 04 '20 at 05:18
  • I think the function you want to look at is named something like `_start` – Barmar Sep 04 '20 at 05:22
  • 2
    It's spilling the register args to memory, because you compiled without optimization. Same as any other function with args. `main` isn't special in this respect. – Peter Cordes Sep 04 '20 at 05:31

0 Answers0