9

main {}使用 ac/c++ 编译器针对有 OS(比如 linux)和没有 OS(比如嵌入式 DSP 目标)的目标编译两个空程序有什么区别?我特别想知道当有操作系统和其他情况时编译器的不同之处。在两种情况下,编译器/语言运行时有何不同?

4

4 回答 4

12

实际上,链接器在打包程序以在操作系统上运行与构建仅在裸硬件上运行的程序时所做的工作不同。编译器仅生成包含针对主机体系结构的指令的目标文件,这些块稍后由链接器组合和打包。

旨在在操作系统上运行的程序必须具有一定的二进制结构——这就是可执行格式发挥作用的地方。例如,这种格式可能规定程序应该在开头有几个标题部分,然后代码应该跟随。操作系统加载器的工作是解释这个结构,然后将代码部分包含的指令流提供给 CPU。

相比之下,旨在在裸硬件上运行的程序通常没有特殊结构,可以直接馈送到 CPU。

于 2012-12-30T14:00:41.297 回答
6

实际上,链接器在打包程序以在操作系统上运行与构建仅在裸硬件上运行的程序时所做的工作不同。编译器仅生成包含针对主机体系结构的指令的目标文件,这些块稍后由链接器组合和打包。

旨在在操作系统上运行的程序必须具有一定的二进制结构——这就是可执行格式发挥作用的地方。例如,这种格式可能规定程序应该在开头有几个标题部分,然后代码应该跟随。操作系统加载器的工作是解释这个结构,然后向 CPU 提供代码部分包含的指令流。

相比之下,旨在在裸硬件上运行的程序通常没有特殊结构,可以直接馈送到 CPU。

我想在 Blagovest 这个写得很好的答案的基础上再接再厉。事实上,正如他所暗示的那样,可执行容器格式和二进制接口以及诸如此类的东西是不同的。然而,最大的区别可能是应用程序代码执行的实际主入口点以及启动代码和运行时库的存在;但是,如果您知道自己在做什么,那么您也可以避免在成熟的操作系统上链接后者。

通常存在启动例程、运行时库(例如 crt0)时,应用程序的实际入口点不是main其他东西(通常是_start. 在这个实际的入口点将控制权交给您main之前,它可能会执行一系列非常具体的任务,通常与初始化有关。

总是有 Wikipedia 以获取有关 crt0 的更多信息

但是,在裸机平台上,编译器可能没有这样的例程。因此,控制权可能会直接交给您main,而要在平台上执行的第一个代码将是您的。

你去吧,这是两种mains 之间最根本的区别。但是,我不得不说你的问题有点模糊,因为如果你自己初始化堆栈等,你可以在没有启动脚本的情况下取消,你也可以使用运行时库来完成所有这些工作(大多数?)裸-金属平台。事实上,这一切都取决于您的编译器套件、您的目标平台等。

于 2012-12-30T14:24:19.917 回答
3

我很想说没有区别。编译器(或翻译系统)所做的很大程度上取决于实现。翻译系统可能为 Windows 做与 Linux 不同的事情,即使两者都符合操作系统的条件。

主要区别在于实现是否托管。如果它不是托管的,那么它甚至可能不支持 main,或者如果它支持,它可能不支持main带参数。非托管实现在启动时所做或需要的是实现定义的。虽然也有很多关于在托管环境中启动的“实现定义”,但实现需要支持 main、返回int和至少两个签名,并且应用程序需要提供这样的功能。

请注意,在过去和今天,许多您认为托管的实现实际上并不是出于各种原因。例如,在过去,g++ 将自己记录为非托管(至少 gcc 是这样),因为他们无法控制并且无法保证实现的库部分。而且即使在今天,微软的 C++ 在生成控制台应用程序时也只能被认为是托管的;Windows 应用程序没有main.

于 2012-12-30T16:19:37.150 回答
0

@BlagovestBuyukliev 提供了一个写得很好的答案。

I'd like to expand it a bit - No OS actually means no software-implemented OS. Piece of HW capable of executing a binary code also has a protocol that handles the loading of the program and feeding it into the CPU and all the rest of low-level details. In this case the "OS" is actually present as a HW implemented one. From this point on the differences between it and standard OS are not principal but technical, as far as the binary code execution considered.

于 2012-12-30T17:08:38.787 回答