(NASM)(80x86)Bootloader NEEDS xor ax,ax

时间:2016-08-31 03:39:32

标签: x86 nasm bootloader

我正在学习如何从osdev制作引导加载程序。我正在使用NASM来组装我的代码,并使用x86机器来运行我的引导加载程序。这是一段打印字符并进入无限循环的代码:

BITS 16

xor ax, ax

mov ah, 0x0E
mov al, 0x41
int 0x10

jmp $

times 510-($-$$) db 0x00
db 0x55
db 0xAA

我的问题是:当我评论'xor ax,ax'指令时,为什么代码不运行?正如您在上面的代码中看到的,ax值被更改为存储中断参数,因此代码应该在没有xor指令的情况下运行...

额外说明:

  • 我使用此命令在Xubuntu下汇编代码: nasm -f bin -o main.bin main.asm

  • 我使用此命令将512字节的机器代码存储到笔式驱动器上: sudo dd if = main.bin of = / dev / sdb

  • 我的电脑可以从笔式驱动器启动

非常感谢你。

2 个答案:

答案 0 :(得分:3)

理论中,在编写BPB而不是MBR 1 时,您不需要VBR xor ax, ax指令的存在不会影响启动 您应该包含xor bh, bhInt 10/AH=0Eh上的更多内容)

可悲的是,这只是理论。

特别是对于USB设备,某些固件隐含地假定BPB,包括完整的FDC描述符(具有有效的OS名称)。
非常感谢Michael Petch强调这一点。

由于UEFI实现的引入,特别是处理CSM (Compatibility Support Module)的部分,即遗留引导,编写完全支持的MBR变得棘手。

固件有时会尝试自动检测要使用的引导模式,并且由于所有UEFI设备也是每个规范的传统设备,因此固件必须依靠一些怪癖来区分它们。

我的固件会将设备检测为“遗留”,即使明确地告知设备,,当其中至少有一个为真时:

  • MBR分区表中有一个可引导的非空分区 CHS或LBA中的起始/结束地址根本不会被检查。
  • 第一条指令是xor ax, ax(格式为33 C031 C0)。 这是因为大多数引导程序首先要做的是通过 AX 将段寄存器设置为零。

可能还有其他“签名”,比如第一个字节的跳转,但我还没有测试过它们。

如果固件无法将设备检测为旧设备,并且它不是符合UEFI标准的设备,则会跳过该设备。

您可以使用xor ax, ax(在这种情况下我建议使用db 33h, 0c0h和文档注释)或添加虚拟分区条目,如下所示。

BITS 16
ORG 7c00h                       ;Soon or later you'll need this

 xor bh, bh
 mov ah, 0x0E
 mov al, 0x41
 int 0x10

_loop:
 hlt                            ;Be eco-friendly
jmp _loop

 ;Pad to the first PTE (Partition Table Entry), it is at 1beh
 TIMES 01beh-($-$$) db 00h

 dd 80h                         ;Bootable partition at CHS 0:0:0 (Which is illegal but not checked)
 db 01h                         ;Non empty partition (Type 1 is MS-DOS 2.0 FAT)

 ;Pad to the end of the sector minus 2
 TIMES 510-($-$$) db 00h
 dw 0aa55h                      ;Signature

1 根据dd命令的参数。

答案 1 :(得分:1)

2018年,我偶然发现了同样的问题。 Micheal的答案和评论似乎是最好的解决方案。我们不是生活在一个完美的世界中,而是它的生活方式。这就是我开始使用OS Dev时想要开发BIOS的原因。我讨厌在没有检查的情况下在我的计算机上运行别人的代码。但是在固件和BIOS的情况下,这太难了。如果您在不知道自己正在做什么的情况下弄乱BIOS,它甚至可能会破坏您的PC。

无论如何,我刚刚添加了此评论,以防其他人在以后偶然发现同样的问题。我会认真地建议检查源代码和/或反向工程一些已经可用的引导程序,如GRUB,Windows启动管理器,LILO等。您还可以为您的PC下载实时USB Linux发行版,将其安装在闪存驱动器中并查看在十六进制编辑器中启动扇区代码,甚至可以反汇编它。

这不是问题的答案,但值得一提。为了使这个更具相关性,我可以说的是我已经反转了GRUB的代码,因为它安装在Kali Linux USB可启动上,它以XOR BP, BP指令开始。