当主要是不带参数的定义,将argc和argv仍然在栈上present? [英] When main is defined without parameters, will argc and argv still be present on the stack?

查看:117
本文介绍了当主要是不带参数的定义,将argc和argv仍然在栈上present?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑很简单:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆