Search code examples
carchitectureoperating-systemprogram-entry-pointvirtual-address-space

Where does the OS store argv and argc when a child process is executed?


I'm having some difficulty understanding how the OS passes data from the address space of a parent process to the address space of a child process. Namely, in a C program, where is argc and argv stored upon being passed into main?

I understand how argv is essentially a double pointer. What I'm not understanding is what the OS does with those values after loading them into the kernel. After creating an address space for the child process does it push these values on the stack of the new space? We obviously don't want to pass in pointers to another address space.

For the record, I'm working with the MIPS32 architecture.


Solution

  • On Linux, at least on the architectures I've played with, the process starts with %esp pointing to something like:

    argc | argv[0] | argv[1] | ... argv[argc - 1] | argv[argc] == NULL | envp[0] | envp[1] ... envp[?] == NULL
    

    The first function called is traditionally named _start, and its job is to calculate (argc = %esp, argv = ((char *)%esp) + 1, envp = ((char *)%esp) + argc + 2), then call main with the appropriate calling convention.

    On x86, the arguments get passed on the stack.

    On amd64, they get passed in registers %rdi, %rsi, and %rdx.

    On mips, Google tells me there are several different calling conventions in use - including O32, N32, N64 - but all of them use $a0, $a1, $a2 first.