我正在学习如何从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
我的电脑可以从笔式驱动器启动
非常感谢你。
答案 0 :(得分:3)
在理论中,在编写BPB而不是MBR 1 时,您不需要VBR xor ax, ax
指令的存在不会影响启动
您应该包含xor bh, bh
(Int 10/AH=0Eh上的更多内容)
可悲的是,这只是理论。
特别是对于USB设备,某些固件隐含地假定BPB,包括完整的FDC描述符(具有有效的OS名称)。
非常感谢Michael Petch强调这一点。
由于UEFI实现的引入,特别是处理CSM (Compatibility Support Module)的部分,即遗留引导,编写完全支持的MBR变得棘手。
固件有时会尝试自动检测要使用的引导模式,并且由于所有UEFI设备也是每个规范的传统设备,因此固件必须依靠一些怪癖来区分它们。
我的固件会将设备检测为“遗留”,即使明确地告知设备,仅,当其中至少有一个为真时:
xor ax, ax
(格式为33 C0
或31 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
指令开始。