(NASM)(80x86)引导加载程序需要xor ax,ax

(NASM)(80x86)引导加载程序需要xor ax,ax,x86,nasm,bootloader,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值被更改以存储中断参数,因此代码应该在没有xo

我正在学习如何从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

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

非常感谢。

理论上,在编写a而不是1时,您不需要a,并且
xor ax,ax
指令的存在不会影响引导。
但是,您应该包括一个异或bh,bh(更多信息)


不幸的是,这只是理论。

特别是对于USB设备,某些固件隐式地采用BPB,包括完整的FDC描述符(具有有效的操作系统名称)。
非常感谢您强调这一点

自从引入实现,特别是处理遗留引导的部分以来,编写完全支持的MBR变得很棘手

固件有时会尝试自动检测要使用的引导模式,因为所有UEFI设备也是符合规范的遗留设备,固件必须依靠一些怪癖来区分它们

我的固件将设备检测为“遗留”,即使明确告知,也仅当至少其中一项为真时才检测到该设备:

  • MBR分区表中有一个可引导的非空分区。
    CHS或LBA中的起始/结束地址根本不检查
  • 第一条指令是
    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
命令的参数

现在是2018年,我偶然发现了同样的问题。Micheal的回答和评论似乎是迄今为止最好的解决方案。我们并不是生活在一个完美的世界里,事实就是如此。这就是为什么我在启动OS Dev时想要开发BIOS。我讨厌在我的计算机上运行别人的代码而不检查它。但这对于固件和bios来说太难了。如果你在不知道自己在做什么的情况下乱用BIOS,它甚至可能会损坏你的电脑

不管怎样,我刚刚添加了这条评论,以防以后有人碰到同样的问题。我会认真地建议检查源代码和/或反向工程一些已经可用的引导加载程序,如GRUB、Windows引导管理器、LILO等。您还可以为您的PC下载live USB linux发行版,将其安装在闪存驱动器中,并在十六进制编辑器中查看引导扇区代码,甚至可以将其反汇编


这不完全是对这个问题的回答,但值得一提。为了使这一点更加相关,我可以说的是,我颠倒了安装在Kali Linux USB bootable上的GRUB代码,它以一条
XOR BP,BP
指令开始。

通常在引导加载程序文件的顶部有
org 0x7c00
,在
XOR ax、ax之后,如果需要,可以将其复制到DS寄存器和ES(不痛)在<代码> MOV DS、AX <代码> >代码> MOVE ES、AX  <代码> XOR AX、AX < /代码> .Case> XOR AX、AX < /C> >与AX-AUX完全相同。因为您在AX和AL正确的情况下重写AH和AL,如果代码“XOR AX,AX < /代码>完成或不执行。您确定它是否有不同的工作?还应该考虑设置SS:SP。(堆栈段和指针)唯一的另一种可能性是BIOS正在(盲目地)覆盖它认为是BPB的内容,而BPB通常出现在引导加载程序的开头(通常在JMP指令之后)如果盲目更新引导程序,可能是在代码加载到RAM中之后BIOS所做的修改导致代码不正确。我建议您在int 10H/AH=0EH之前考虑做“代码> XOR BX、BX < /代码>,因为BH被假定为要写入的页码(设置为0)。。可以找到有关BIOS参数块的更多信息。
xor ax,ax
在一个工作的引导加载程序中根本不需要。真实的硬件有一些奇怪的怪癖,你在bochs、qemu、virtualbox等虚拟环境中通常看不到。@RyanB:见Peter的答案。他有。IRC聊天中也提到过。我暗示了这个想法恩,我提到“真正的硬件有一些奇怪的怪癖,你在bochs、qemu、virtualbox等虚拟环境中通常看不到。”但作为一个暗示,它可能有点迟钝。哈哈,我会再次投票支持这个环保评论:)认为您不需要BPB是错误的。您可能不使用太多实际的硬件,但在USB引导过程中,许多BIOS会写入介质的驱动器几何图形(如BIOS所示)进入BPB区域。如果您有BIOS认为BPB所在的代码,一些BIOS会盲目地向该区域写入BPB。其他BIOS会尝试检查USB设备的第一条指令是否为JMP指令(有些是哑指令,甚至不检查它是否为2)