首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪种机制知道程序的入口点是main()

哪种机制知道程序的入口点是main()
EN

Stack Overflow用户
提问于 2020-02-11 18:50:40
回答 1查看 758关注 0票数 3

应用程序如何知道它的入口点是main()函数?

我知道一个应用程序不知道它的入口点是main() --它通过语言规范直接指向main()函数,不管它是什么。

此时,规范实际上是在哪里声明的?例如,在C中,入口点应该是main()函数。是谁为程序提供了这种机制?操作系统还是编译器?

在Visual中分解了一个简单的规范示例"Hello“之后,我开始了这个问题。

在这段代码中,只有几行代码和一个函数main()

但在对其进行分解后,内存空间中存在着大量的定义和宏,main()并不是唯一的声明和定义。

下面是拆解部分的截图。我也知道在语言定义中有一个严格的规则,只有一个main()函数必须被定义和存在。

总结我的问题:我想知道是哪种机制指导或设置了main()函数作为应用程序的入口点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-11 21:22:58

应用程序不知道main()是入口点。首先,我们假设C不是C++,尽管有你的照片。

对于C,"C“入口点是main()。但是您不能只是在那里开始执行,因为我们有更多的假设,更多的是规则,在C中,例如.data需要初始化,.bss为零。

代码语言:javascript
复制
unsigned x = 1;
unsigned int y;

我们期望当main()被击中x=1时,大多数人假设并且可能指定y=0时,我不会做这个假设,但无论如何。

我们还需要一个堆栈指针,并需要处理argc/argv。如果是C++,那么还有其他事情要做。即使对C来说也是如此。

应用程序通常不知道这其中的任何一个。您可能正在使用C库,并且该库负责引导代码,引导代码在main()之前,以及链接器的链接器脚本,因为引导程序和链接器脚本密切相关。根据某些实现,人们可能会认为C库与工具链是可分离的,正如我们所知道的,使用GNU时,您可以从不同的工具链中选择不同的库,并且这些库具有不同的引导和链接脚本。但是我相信有很多是密切相关的,还有库和操作系统之间的关系,因为很多C库调用都是在一个或无数个系统调用中结束的。

您设计一个操作系统,假设它支持运行时可加载的应用程序是操作系统加载程序支持的文件格式的一部分,操作系统加载程序希望支持的特性以及它们如何与文件格式重叠,操作系统定义文件格式的情况并不少见,但是对于精灵和其他人(毫无疑问,不是偶然或独立创建的),您有机会使用像elf这样的现有容器。操作系统设计及其加载程序决定了很多事情,与所有这些规则相结合的C库必须遵循所有这些规则,如果集成到编译器中,编译器也必须发挥作用。

并不是应用程序知道它是系统设计的一部分,而应用程序只是所有这些的从属程序,当您在该平台上为该平台编译所有这些规则和关系时,您正在将这些规则和关系放入其中的很小一部分,其余的部分已经到位,支持什么样的文件格式,每种格式所需的信息,编译器/库解决方案必须提供的规则。系统设计规定如果.data和.bss是由加载程序或应用程序归零的,我的意思是引导而不是程序的用户部分,您不能在C中引导C,因为C需要引导,而如果引导是在C中,则C需要引导等等。

代码语言:javascript
复制
int main ( void )
{
    return 0;  
}

在编译程序时,背景中有很多事情要做,而不仅仅是实现该代码所需的少量指令。

在windows、Linux和mac上编译程序,每个或每个C库都有不同版本的编译器,以及每个库的不同版本等等。您应该看到的是,即使是同一台目标ISA、同一台计算机,也有一定百分比的组合可能会为函数选择相同的几条指令,所围绕的指令可能是相似的,但并不相同。如果有些实现彼此之间有很大的不同,就没有理由感到惊讶了。

所有这些都适用于将程序加载到ram中并运行它们的成熟操作系统,因为如果两者之间的差异更大,嵌入式系统也不会感到惊讶。在一个完整的os中,您可能期望看到一个mmu,并且应用程序至少为.text、.data、.bss获得一个基于零的地址空间,这样所有的解决方案都可能有一个最喜欢的位置或最喜欢的部分,按相同的二进制顺序排列,但每个部分的大小可能是特定于实现的。顺序/大小可能因C库版本或编译器版本等而异。

神奇之处在于系统设计。这不是魔术,那是设计。main()不能直接输入,而且语言的各个部分仍然像.data和.bss init那样工作,可以在条目之前解决堆栈指针,但是.data和.bss是如何和在哪里特定于应用程序的,因此不能由一个简单的分支从OS处理。

您的工具链的链接器可以以各种方式被告知,其中的入口点可以被假定/指定为该工具/目标或命令行选项或链接器脚本选项,或者是您在标签上或设计人员选择的任何特殊符号。main被假定为C入口点,尽管这实际上并不意味着在它之前可能有一些C代码,但是通常有一些asm (不能用C引导C),然后是到main()的一个或多个步骤。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60175571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档