在文件末尾定义单词 - Assembly / C ++

时间:2017-04-28 03:55:54

标签: assembly visual-studio-2017

我正在尝试用C ++编写引导扇区。为了做到这一点,我必须在二进制文件的末尾添加单词0xaa55。 C ++允许通过" __ asm"使用内联汇编。关键字后跟花括号。这将汇编代码放在c ++源代码中的任何地方。我希望能够使用" dw"在文件的末尾定义一个单词。命令。当C ++在编译时围绕内联汇编生成汇编代码时,我该怎么做?我使用Windows 10 Visual Studio 2017进行开发。我目前正在使用Microsoft的C ++编译器。谢谢!

1 个答案:

答案 0 :(得分:3)

不幸的是,这是不可能的。问题很多:

您无法完成立即任务,因为无法强制Microsoft的C ++编译器在结束时发出特定的字节序列。码。当你用C ++编写时,你对这个没有足够的控制权。语法不存在以表达它,即使它存在,您也不能保证编译器/链接器符合它并在正确的位置发出字节。

此外,引导加载程序代码在x86上非常特殊,必须以非常精确的格式编写。除了最后需要这两个签名字节之外,还需要确保在引导扇区的开头处找到正确的指令序列(您无法获得要发出的C ++编译器,要么,你需要确保整个引导扇区正好是512字节(填充到最后,最后两个字节是0xAA55)。您无法获得MSVC来生成大小恰好为512字节的代码。没有办法强制执行长度,即使有,也可能会比C ++代码大得多,因为......

MSVC的工具链(编译器和链接器)没有提供任何生成" raw"二进制文件。他们创造的唯一的东西就是Win32 PE格式的可执行文件,它们会有一堆标题和你不需要而且不需要在引导加载程序中的东西。我想你可以使用十六进制编辑器返回并删除这些东西,但是一旦你这样做了,你也可以用汇编语言编写这个糟糕的东西并得到你想要的东西。

此外,MSVC的工具链还没有支持16位代码的生成(因为x86 CPU以16位模式启动以实现兼容性,因此引导加载程序需要)近25年。可以生成16位代码的最后一个版本是Visual C ++ 1.52c,专为Windows 3.1设计。您可以在某处找到这个以便下载" abandonware"网站。这种合法性是可疑的,但我必须说,如果您拥有现代版Visual Studio的合法许可,我个人个人没有问题。但是,在现代版本的Windows上运行它可能会遇到问题,这意味着您需要设置Windows 3.1(或者可能是95)虚拟机。即使你设置VC ++ 1.52c,你也不会没有家庭,因为C ++编译器/链接器仍然不是为了创建原始二进制文件或生成引导加载程序而设计的。您仍然无法获得所需的细粒度控制。

Bootloader应该用汇编语言编写。因为它们最多可以是512个字节,所以它们所做的并不是很复杂,而且你在网上找到的大多数文档都假设是汇编语言,这实际上并不像听起来那么令人生畏。如果您具备编写引导程序所需的知识,那么您或者已经知道了足够的装配,或者是时候您已经弄明白了。

现在,所有版本的Visual C ++都附带了Microsoft的宏汇编程序(MASM),这正是您想要的 - 将汇编语言代码组装成原始二进制文件的方法。问题是,自版本6.0-ish以来,MASM还不支持16位代码生成,随VC ++ 1.52c一起提供(也单独出售)。同样,您可以在各种" abandonware"上下载这些旧版本。站点,你可能会在现代机器上运行它的问题更少,因为它是一个简单的命令行二进制文件(虽然你无法在64位版本的Windows上运行它,因为它是所有16位代码)。但是你应该注意你已经使用了不再支持的过时软件,更不用说使用它在法律上是可疑的了,所以你可能想重新考虑。

使用不同的汇编程序会好得多。 NASM是一个非常好的选择。以NASM格式汇编语言编写的示例引导加载程序代码的。我们自己的Michael Petch已经在Stack Overflow上写了数百个答案,这些答案涵盖了这个主题。 NASM的另一种选择是Open Watcom,这是现代的开源重新发布的经典Watcom工具链。 Watcom的C / C ++编译器是最好的"在当天优化代码,但更重要的是为了您的目的,附带一个可以构建16位二进制文​​件的汇编程序(WASM)。 Open Watcom在线提供的帮助并不多,尽管有一点点,语法基本上与MASM兼容。这些都可以在现代版本的Windows(或OS X,或Linux,或OS / 2,...)上正常运行。