7

我已经通过在软盘上制作一个小型程序集引导加载程序搞砸了几次,并且想知道是否可以在 C++ 中制作一个引导加载程序,如果可以,我可以从哪里开始?据我所知,我不确定它是否会使用int main().

谢谢你的帮助。

4

4 回答 4

9

如果您正在编写引导加载程序,那么您实际上是从零开始:一小段代码被加载到内存中并执行。您可以用 C++ 编写大部分引导加载程序,但首先需要引导您自己的 C++ 运行时环境。

组装确实是第一阶段的唯一选择,因为您需要设置一个合理的环境来运行任何更高级别的东西。做足够多的事情来运行 C 代码是相当简单的——你需要:

  • 代码和数据加载在正确的位置;
  • 可能有额外的部分数据区域必须进行零初始化;
  • 您需要将堆栈指针指向堆栈的合适内存区域。

然后,您可以在适当的位置(例如main())跳转到代码中,并期望基本的语言功能能够正常工作。(可能已经实现或链接的标准的任何功能都可能需要在此阶段进行额外的初始化。)

为 C++ 获得合适的环境需要更多的努力,因为它需要更多的初始化,并且还具有需要运行时支持的核心语言特性(同样,这是在考虑库特性之前)。这些包括:

  • 运行静态构造函数;
  • 内存分配以支持newdelete
  • 支持运行时类型信息 (RTTI);
  • 支持例外;
  • 可能还有一些我忘记提及的事情。

在 C 环境启动并运行之前,这些都不是必需的,因此处理这些的代码可以用 C 而不是汇编程序编写(或者甚至在不使用上述特性的 C++ 子集中)。

(同样的原则适用于嵌入式系统,此类系统使用 C++ 的情况并不少见,但仅限于有限的方式——例如,没有例外和/或 RTTI,因为未实现运行时支持。)

于 2010-07-17T23:45:37.233 回答
3

自从我玩写引导加载程序已经有一段时间了,所以我要记忆犹新了。

对于 x86 引导加载程序,您需要有一个可以发出 x86 程序集的 C++ 编译器,或者,至少,您需要在 16 位程序集中编写自己的前导码,将 CPU 置于 32 位保护(或 64 -bit long) 模式,然后才能调用 C++ 函数。

但是,一旦你完成了这些,你应该能够使用 C++ 的大部分(如果不是全部)语言特性,只要你远离需要底层 libc 的东西。但是在没有 CRT 的情况下静态链接所有内容,你就是金子。

于 2010-07-17T22:10:30.423 回答
2

引导加载程序没有“int main()”,除非您编写汇编代码来调用它。如果您正在编写第 1 阶段的引导加载程序,那么非常不鼓励这样做。

否则,osdev.org上有关于该主题的大量文档。
虽然可能可以在 C++ 中创建引导加载程序,但请记住不要将您的代码链接到任何动态库,并记住仅仅因为它是 C++,这并不意味着您可以/应该使用 STL 等。

于 2010-07-17T22:01:24.643 回答
2

对的,这是可能的。你有这个问题的答案元素和有用的链接

你也可以看看这里,有一个 C++ 引导加载程序示例。

要了解的主要内容是,您需要创建一个平面二进制文件,而不是通常花哨的可执行文件格式(Windows 上的 PE,或 Unix 上的 ELF),因为这些文件格式需要操作系统来加载它们,并且在引导加载程序中您还没有操作系统。

如果您静态链接,则使用库不是问题(没有动态链接,因为上述可执行问题再次出现)。但显然所有与 OS API 相关的入口点都不可用......

于 2010-07-17T22:06:27.610 回答