I am used to seeing command line arguments referenced by (convention (A)):
pushl %ebp
movl %esp, %ebp
movl (%ebp), %eax # argc
movl 4(%ebp), %ebx # pointer to argv[0] string
movl 8($ebp), %ecx # pointer to argv[1] string
Sometimes, I've seen the list start at an offset of 8, and this is not the (main) question. What I've noticed in a program is this translation and reference which I am confused about, to get argv[1]
(convention (B)):
movl 0xc(%ebp), %eax # pointer to a pointer to argv[0] (argc is at offset 8)
addl $0x4, %eax # argv[1] is a pointer at offset 4 from the pointer to argv[0]
movl (%eax), %eax # load where it points to, which is the argv[1] string
(at offset 16(%ebp)
I see a pointer to an environmental variable)
(1) Is there any reason for this different convention?
(2) Is there a compiler option to force gcc to use what I believe to be the standard convention (A) above?
(3) Is there a reason gcc uses convention (B)?
(4) Why the additional offset of 8?
System info:
- Ubuntu 12.04
- gcc 4.6.3
- compiled with fno-stack-protector