【发布时间】:2010-07-17 21:53:17
【问题描述】:
我在软盘上制作了一个小型程序集引导加载程序,并想知道是否可以在 C++ 中制作引导加载程序,如果可以,我可以从哪里开始?据我所知,我不确定它是否会使用int main()。
感谢您的帮助。
【问题讨论】:
-
我相信是有区别的。这个问我应该如何进行,另一个是关于 C 和 C++ 之间的选择。但有一些重叠。
标签: c++ assembly bootloader
我在软盘上制作了一个小型程序集引导加载程序,并想知道是否可以在 C++ 中制作引导加载程序,如果可以,我可以从哪里开始?据我所知,我不确定它是否会使用int main()。
感谢您的帮助。
【问题讨论】:
标签: c++ assembly bootloader
如果您正在编写引导加载程序,那么您实际上是从无到有:一小段代码被加载到内存中并被执行。您可以用 C++ 编写大部分引导加载程序,但您需要先引导自己的 C++ 运行时环境。
Assembly 确实是第一阶段的唯一选择,因为您需要设置一个合理的环境来运行任何更高级别的东西。做足够多的事情来运行 C 代码是相当简单的——你需要:
然后您可以在适当的位置(例如main())跳转到代码,并期望基本的语言 功能能够正常工作。 (可能已经实现或链接的标准库的任何功能都可能需要在此阶段进行额外的初始化。)
获得一个适合 C++ 的环境需要更多的努力,因为它需要更多的初始化,并且还具有需要运行时支持的核心语言特性(同样,这是在考虑库特性之前)。其中包括:
new和delete;在 C 环境启动并运行之前,这些都不是必需的,因此处理这些的代码可以用 C 而不是汇编器编写(甚至可以用不使用上述特性的 C++ 子集编写)。
(相同的原则适用于嵌入式系统,此类系统使用 C++ 的情况并不少见,但仅以有限的方式使用——例如,没有例外和/或 RTTI,因为未实现运行时支持。)
【讨论】:
我已经有一段时间没有玩写引导加载程序了,所以我要记忆犹新了。
对于 x86 引导加载程序,您需要有一个可以发出 x86 程序集的 C++ 编译器,或者,至少,您需要在 16 位程序集中编写自己的前导码,将 CPU 置于 32 位保护状态(或 64 位长)模式,然后才能调用 C++ 函数。
不过,一旦你这样做了,你应该能够使用 C++ 的大部分(如果不是全部)语言特性,只要你远离需要底层 libc 的东西。但是没有 CRT 的情况下静态链接所有东西,你就是金子。
【讨论】:
引导加载程序没有“int main()”,除非您编写汇编代码来调用它。 如果您正在编写阶段 1 引导加载程序,那么非常不鼓励这样做。
否则,osdev.org 有关于该主题的大量文档。
虽然是可能在 C++ 中创建引导加载程序,但请记住不要将您的代码链接到任何动态库,并记住仅仅因为它是 C++,这并不意味着您可以/应该使用STL等
【讨论】:
是的,这是可能的。 this question中有答案元素和有用的链接
你也可以看看here,有一个C++ bootloader例子。
要了解的主要内容是,您需要创建一个平面二进制文件而不是通常花哨的可执行文件格式(Windows 上的 PE,或 Unix 上的 ELF),因为这些文件格式需要操作系统来加载它们,并且在您还没有操作系统的引导加载程序。
如果您静态链接,使用库不是问题(没有动态链接,因为上述可执行问题再次出现)。但显然所有与 OS API 相关的入口点都不可用...
【讨论】: