当主要是不带参数的定义,将argc和argv仍然在栈上present? [英] When main is defined without parameters, will argc and argv still be present on the stack?
问题描述
考虑很简单:
int main(void) {
return 0;
}
我编译它(用的mingw32-GCC),并执行它作为 MAIN.EXE富栏
。
现在,我所预料的某种崩溃或错误导致的主要功能明确声明为丧失的<击>生活击>参数。缺少的错误导致了这个问题,这实在是四个问题。
Now, I had expected some sort of crash or error caused by a main function explicitly declared as being bereft of life parameters. The lack of errors led to this question, which is really four questions.
-
为什么这项工作? 答:因为标准是这样说的
是输入参数,只是忽略或不符合的argc和放大器ppared堆栈$ P $; argv的默默? 答:在这种特殊情况下,堆栈prepared
Are the input parameters just ignored or is the stack prepared with argc & argv silently? Answer: In this particular case, the stack is prepared.
如何验证上面? 答:查看rascher的答案
How do I verify the above? Answer: See rascher's answer.
这是平台相关的? 答:是,并没有
Is this platform dependant? Answer: Yes, and no.
推荐答案
我不知道跨平台回答你的问题。但是,这让我很好奇。那么我们该怎么办?看看堆栈!
I don't know the cross-platform answer to your question. But this made me curious. So what do we do? Look at the stack!
有关的第一次迭代:
test.c的
int main(void) {
return 0;
}
test2.c中
test2.c
int main(int argc, char *argv[]) {
return 0;
}
和现在看汇编输出:
$ gcc -S -o test.s test.c
$ cat test.s
.file "test.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
平平淡淡这里。除了一件事:两个C程序具有相同的汇编输出
这基本上是有道理的;我们从来没有真正要推/流行什么关栈的main(),因为它是在调用堆栈上的第一件事。
This basically makes sense; we never really have to push/pop anything off of the stack for main(), since it's the first thing on the call stack.
于是我写了这个程序:
int main(int argc, char *argv[]) {
return argc;
}
和它的ASM:
main:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
ret
这告诉我们,ARGC位于 8(%EBP)
This tells us that "argc" is located at 8(%ebp)
所以,现在有两个以上的C程序:
So now for two more C programs:
int main(int argc, char *argv[]) {
__asm__("movl 8(%ebp), %eax\n\t"
"popl %ebp\n\t"
"ret");
/*return argc;*/
}
int main(void) {
__asm__("movl 8(%ebp), %eax\n\t"
"popl %ebp\n\t"
"ret");
/*return argc;*/
}
我们已经从上面偷回ARGCcode和它粘贴到这两个程序的ASM。当我们编译和运行这些,然后调用回声$?
(其中回声的previous过程的返回值),我们得到正确的答案。 ?所以,当我运行./test A B C D,那么 $
给我5两个节目 - 即使只有一个人的argc / argv的定义。这告诉我,我的平台上,ARGC可以肯定的是放置在堆栈中。我敢打赌,类似的测试将确认本作的argv。
We've stolen the "return argc" code from above and pasted it into the asm of these two programs. When we compile and run these, and then invoke echo $?
(which echos the return value of the previous process) we get the "right" answer. So when I run "./test a b c d" then $?
gives me "5" for both programs - even though only one has argc/argv defined. This tells me that, on my platform, argc is for sure placed on the stack. I'd bet that a similar test would confirm this for argv.
试试这个在Windows!
Try this on Windows!
这篇关于当主要是不带参数的定义,将argc和argv仍然在栈上present?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!