Sha*_*han 9 c c++ compiler-construction operating-system runtime
main {}
当使用ac/c ++编译器为OS(比如linux)和没有OS(比如嵌入式DSP目标)编译时,两个空程序有什么区别?我特别想知道当存在操作系统时编译器的作用会有所不同.两种情况下编译器/语言运行时有何不同?
Bla*_*iev 12
实际上,链接器在打包程序以在操作系统上运行时执行不同的工作,而不是构建仅在裸硬件上运行的程序.编译器仅生成包含针对主机体系结构的指令的目标文件,并且这些块稍后由链接器组合和打包.
一个旨在在操作系统上运行的程序必须具有某种二进制结构 - 这是可执行格式发挥作用的地方.例如,这种格式可能要求程序在开头应该有几个标题部分,然后代码应该跟随.OS加载程序的工作是解释此结构,然后向CPU提供代码部分包含的指令流.
相比之下,要在裸硬件上运行的程序通常没有特殊的结构,可以直接送到CPU.
小智 6
实际上,链接器在打包程序以在操作系统上运行时执行不同的工作,而不是构建仅在裸硬件上运行的程序.编译器仅生成包含针对主机体系结构的指令的目标文件,并且这些块稍后由链接器组合和打包.
一个旨在在操作系统上运行的程序必须具有某种二进制结构 - 这是可执行格式发挥作用的地方.例如,这种格式可能要求程序在开头应该有几个标题部分,然后代码应该跟随.OS加载程序的工作是解释此结构,然后向CPU提供代码部分包含的指令流.
相反,要在裸硬件上运行的程序通常没有特殊的结构,可以直接送到CPU.
我想借助布拉戈维斯特写得非常好的答案.事实上,他建议可执行容器格式和二进制接口之间存在差异等等.但是,最大的区别可能是执行应用程序代码的实际主要入口点以及启动代码和运行时库的存在; 虽然,如果你知道你在做什么,你也可以避免在完整的操作系统上与后者联系起来.
通常,如果存在启动例程,运行时库(例如crt0),则应用程序的实际入口点不是main
其他内容(通常_start
).在此实际入口点之前将控制权交给您,main
它可能会执行一系列非常具体的任务,通常与初始化有关.
有关crt0的更多信息,总是有维基百科.
但是,在裸机平台上可能没有与编译器捆绑在一起的例程.因此,控件可能会直接发送给您,main
并且在平台上执行的第一个代码将是您的.
你去,这是两种main
s 之间最根本的区别.但是,我不得不说你的问题有点模糊,因为你可以在没有启动脚本的情况下解决,如果你自己初始化堆栈等,你也可以使用运行时库来完成所有这些(大多数?)裸 - 金属平台.实际上,这完全取决于您的编译器套件,您要定位的平台等.