argv is on main's stack right? so where is argv[0][0]?
Printable View
argv is on main's stack right? so where is argv[0][0]?
> so where is argv[0][0]?
Probably in allocated memory (via malloc), since it has no way of knowing how many command line parameters there will be, nor the length of each one.
maybe you misunderstood where i was getting at with my question, or i misunderstood your answer...i'll rephrase
'who' allocated the memory for the argument list? to me it seems like the arguments are not local to "this" program...
>> 'who' allocated the memory for the argument list?
the system your program is running under.
Between the OS and your program which begins at main(), there is a bit of software which takes whatever the OS provides and produces a consistent list of arguments which can be passed to main().
This is called the "C runtime". You typically see an object file "crt.o" being linked with your code if you enable verbose mode when you compile a program.
This is one of the many files which get linked into a program on my system.
_start is the real start of your program, and is the address the program loader jumps to when your program first lands in memory.Code:$ nm /usr/lib/gcc-lib/i386-redhat-linux/3.2/../../../crt1.o
00000000 D __data_start
00000000 W data_start
U _fini
00000000 R _fp_hw
U _init
00000004 R _IO_stdin_used
U __libc_start_main
U main
00000000 T _start
__libc_start_main is an external symbol which is probably resolved by the libc standard library. I imagine it does startup things like initialising the seed for rand() say, and creating stdin, stdout, stderr.
main is of course provided by you.
So at some point, this code ends up doing (void main'ers - take note)
After your program has done what it needs to, the "CRT" tidies up and gets "result" back to the operating system.Code:int result = main ( argc, argv );
that makes a bit more sense now. thank you.
straying from the topic a bit:
solely for the sake of understanding, would
int main(){return 0;} be the same as
void main() { __asm mov eax, 0 }
(given there is an eax register and pretending "mov eax, (constant) 0" is legal)
Nobody said my processor was an X86
On an x86, with a compiler that doesn't, I don't know, zero out eax on a return from a void function, and the compiler further accepting the (by the standard forbidden) void return type on main, yes, that would be possible.
But what is the point???
On an x86 machine no special memory is allocated for command line arguments. There is a special "block" of data immediately before the segment where your programs data begins in memory called the PSP (Program Segment Prefix). This block is populated with numerous data, the last of which is called the command tail. This command tail is where arguments to a program are placed when it is executed.
>> solely for the sake of understanding, would
it depends on your compiler, of course. mine produces:
the output is the same whether I use int main() and return a value or void main() and return nothing, thus the latter is implicitly converted to the former (in accordance with the standard).Code:push ebp
mov ebp, esp
xor eax, eax
pop ebp
ret
Where does the standard say that void main is acceptable, much less that it gets converted to an int main that always returns 0?Quote:
(in accordance with the standard)
I didn't articulate my argument very well, did I?
>> void main() { __asm mov eax, 0 }
my point was that main() *must* return an int - and does so even if you try to declare it as void.
Oh, ok, got it.
> in memory called the PSP (Program Segment Prefix).
That is only true of DOS .COM files.
Things are very different in win32 executables - for example, you aren't limited to the piffling 128 bytes of command line arguments.
And it might yet again be different in ELF executables and a.out executables.