0

因此,我已经在互联网上搜索了数周,但找不到我的问题的答案。

我可以看到 gcc 添加的开始符号设置了最初的两个参数(int argc,char *argv[]),我相信第三个环境参数,但我对此有几个问题。如果 main() 函数被定义为没有参数,为什么还要添加所有这些?如果它只调用 _main 而没有任何参数,它不会节省空间(和技术上的处理时间)吗?其次 push $0x0 是做什么的?我已经完成了测试,如果您尝试像默认开始符号那样迭代命令行参数,那么您需要在开头 push $0x0,否则如果我执行以下操作,我会创建未对齐的堆栈错误:

push $0x00
call _main
mov %eax, %edi
call _exit

同样在我的调查中,我发现链接器在链接到 crt1.10.6.o 时添加了起始符号

任何解释或文件将不胜感激

4

1 回答 1

1

如您所见,的代码_start来自一个名为crt1.o或类似的目标文件。该目标文件通常来自作为 C 库一部分的源代码。它是在不知道您如何声明函数的情况下编译的main,因此它必须假设您希望使用所有三个潜在参数。即使main不使用它们,设置参数也没有害处(正如你提到的,除了微不足道的空间和时间)。

我推断mov %eax,%edi这是 x86-64 ELF ABI,这意味着没有帧指针,所以push $0x00正如您推测的那样,确实只是为了保持堆栈与 16 字节边界对齐。(在 x86-32 ELF ABI 中,它也可以作为帧指针链表的终止符。)

于 2012-06-17T22:45:01.487 回答