1

我不确定这个问题是否有意义,但我一直在写基本的汇编函数以在编写 C 代码时使用(C 代码输出为 16 位汇编,输出为16 位原始二进制文件)。这都是我寻求更好地理解/编写 C 和汇编的追求的一部分,也是我寻求理解操作系统如何在概念级别上运行的所有追求。

为了确保我的功能正常工作,我一直在使用 bios 引导扇区签名以实模式加载原始二进制文件。

当我在 virtualbox 上将二进制文件作为 .flp 加载时,无论是通过 IDE 控制器还是软盘控制器,屏幕上的输出都完全符合预期。有两个单词,中间有空格。

但是,当我使用 U 盘在真实机器上加载相同的代码时,第一个单词中的两个字母丢失了。第二个字的写法完全符合预期。

有什么理由会出现这种差异吗?我在三台不同的真机(不是虚拟盒子)上加载了相同的代码,并且第一个单词中相同的两个字母丢失了。我尝试了不同的 U 盘;我还用两台不同的机器将原始图像加载到 USB 上以确保。

我使用 dd 实用程序编写了我在 virtualbox 上使用的 .flp 图像(同样,virtualbox 的输出没有问题)。我还使用 dd 实用程序将 .flp 映像写入 U 盘。我还将 .bin 直接写入 USB 记忆棒,这并没有什么不同。

我知道代码本身没有任何问题,因为它在 virtualbox 上完美输出。当引导到真机上时,它的第一个单词中奇怪地缺少这两个字母。同样,有两个单词应该输出到屏幕上。

缺少的两个字符不是可能无法普遍支持的奇怪字符;它们都是小写字母。

谢谢你的帮助!

最终编辑:此问题是由 BIOS 从程序中的字节 2-48 对二进制程序执行恶意操作引起的。从迈克尔在评论中的链接来看,这似乎与 BIOS 在启动时处理 USB 记忆棒的方式有关(这解释了为什么当我从虚拟盒中的软盘启动时它不是问题)。当我将程序向下移动 48 个字节时,问题就消失了。

所以我的代码看起来像(在 as86 汇编语法中):

ORG 0x7c00
jmp main
.word 0x0000

ORG 0x7c30
main:
    (calls putchar function 9 times)

putchar:
    (function that prints function argument using int 0x10)

ORG 0x7DFE
.word 0xAA55

正如我在评论中所说,我很想知道为什么 BIOS 会覆盖 USB 记忆棒的前 512 字节或从 0x7c00 开始的 512 字节内存中的任何内容。我不知道它是什么,是在将内容传输到内存之前覆盖U盘,还是覆盖内存。我可以通过加载程序一次然后在启动加载后对 USB 中的二进制文件执行 hexdump 来找出答案,但我还没有这样做。无论如何,这些位置的覆盖看起来很奇怪,因为仅根据 BIOS 约定使用前 512 个字节(最后带有签名),并且仅根据 BIOS 约定,CPU 在加载后指向 0x7c00进入记忆。所以我想我的意思是 BIOS 肯定知道这些位置会有指令和数据。那么,为什么 BIOS 不在 USB 记忆棒或内存中的其他位置执行它需要做的任何事情(取决于它是在记忆棒上覆盖还是在内存中覆盖)?

4

0 回答 0