According to the System V ABI for x86, esp should be pointing at argc when entering main. However, I've seen many binaries where argc instead is retrieved from esp + 4, or esp + 8. Is this correct, or am I missing something? Also, why do these offset differ?

Figure 3-31

  • some of your comments were deleted for violating the code of conduct. Please review it.
    – julian
    Apr 13, 2020 at 1:10
  • 1
    Consider that "main" is not always the program's entry point. There may be initialisation routines added at compile time before. If this happens, then the init procedure calls "main", pushing argc on the stack. After the call, [ESP] will point to the return address and [ESP+4] will contain argc. At the beginnig of main, a PUSH EBP will move ESP another 4 bytes back, now [ESP+8]=argc.
    – Yotamz
    Apr 13, 2020 at 12:00
  • @Yotamz yes, I figured that much. In that case, neither _start nor main have esp pointing at argc, so neither comply with what the ABI says, correct?
    – Martin
    Apr 14, 2020 at 13:46

1 Answer 1


I think your confusion stems from the fact that quoted part of the spec is talking about the process entry point which is a different concept from the C main function. The main is called by the C library startup code so it will follow the standard calling sequence rather than "Initial process stack layout". For 386, it means that argc will be the first value passed on the stack after the return address, and argv will be the second. I.e. at the beginning of main, the layout will look like this

|                |
| argv           | <-- esp+8
| argc           | <-- esp+4
| return address | <-- esp

If the compiler decides to use the frame pointer, then argc will be typically accessed as [ebp+8] due to the extra 4 bytes taken by the saved ebp.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.