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

标签 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

  • 我的电脑可以从随身碟启动

非常感谢。

最佳答案

理论上您不需要 BPB在写 MBR 时而不是 VBR 1,并且xor ax, ax指令的存在不会影响启动。
你应该包含一个 xor bh, bh 然而(更多关于 Int 10/AH=0Eh )


遗憾的是这只是理论。

特别是对于 USB 设备,BPB 由某些固件隐式假定,包括完整的 FDC 描述符(具有有效的操作系统名称)。
非常感谢 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命令的参数。

关于x86 - (NASM) (80x86) 引导加载程序需要 xor ax, ax,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39240353/

相关文章:

macos - 在OSX x64程序集中使用RIP相对寻址

数组迭代中的 CPU 空间缓存位置

c++ - VC++ 2010 - 尝试 DLL 时未声明的标识符,少量代码

assembly - AT&T 语法汇编浮点运算引用

compilation - x86 中的基本 block 和控制流

assembly - 使用 BIOS 中断进行保护模式是好是坏?

assembly - 为什么在将立即值添加到内存地址处的值时需要消除歧义

c - 反汇编 C 代码

assembly - x86 NASM 'org' 指令含义

gcc - 将 NASM 和 64 位 C 代码编译并链接到引导加载程序中