如何从扇区加载应用程序?

How to load application from sectors?

我正在创建必须加载存储在接下来的 32 个扇区中的应用程序的自定义 MBR,除了加载应用程序外一切正常,我不明白我做错了什么,所以如果有人知道什么以及如何修复它,请帮助我。

Victoria.asm

org 0x7c00
bits 16

Kernel:
    ;---Setup Segments
    xor ax, ax               ;AX=0
    mov ds, ax               ;DS=ES=0 because we use an org of 0x7c00 - Segment<<4+offset = 0x0000<<4+0x7c00 = 0x07c00
    mov es, ax
    mov ss, ax
    mov sp, 0x7c00           ;SS:SP= 0x0000:0x7c00 stack just below bootloader

    ;---Read Kernel
    mov bx, buffer           ;ES: BX must point to the buffer
    mov [BOOT_DRIVE], dl     ;save the boot drive
    mov dl, [BOOT_DRIVE]     ;use boot drive passed to bootloader by BIOS in DL
    mov dh,0                 ;head number
    mov ch,0                 ;track number
    mov cl,2                 ;sector number
    mov al,128               ;number of sectors to read
    mov ah,2                 ;read function number
    int 13h

    ;---Start Application
    jmp buffer

;Fake MBR Signature
BOOT_DRIVE: db 0
times 510 - ($ - $$) db 0
dw 0xAA55

;Victoria Freeware - The Kernel
victoria: incbin "Victoria.com"
times 65536 - ($ - $$) db 0

;Buffer
buffer:

主要问题是,当您调用 int 0x13, ah = 0x02 时,您需要 dl 中要读取的设备的设备编号。您启动的设备编号由 BIOS 在 dl 中提供给您,但代码会覆盖它(之前的 mov dx, 0x184F),因此您要求从一个完全不同的设备(可能不存在)。

还有多个其他问题。段寄存器设置不正确(例如 mov ax,ds 而不是 mov ds,ax)并且没有设置在正确的位置(应该在使用段之前完成 - 例如在 ds 段被代码中的 mov al,[si] 指令用来打印一个字符串)。你不能只是假设 int 0x13, ah = 0x02 工作而不检查错误(如果有错误你应该显示 nice "end user readable" error message/s 让用户有希望弄清楚他们能做什么解决问题)。

最后还有一个概念问题。对于分区设备(硬盘驱动器、USB 闪存等),MBR 应该做的主要事情是从活动分区启动操作系统的引导加载程序(MBR 不应被视为任何特定操作系统的一部分,操作系统的引导代码开始与操作系统分区的第一个扇区)。对于未分区的设备(软盘),由于各种原因你需要一个 BPB(BIOS 参数块)(这样其他操作系统就不会认为磁盘未格式化,并且 BIOS 认为它对各种特殊情况有效,例如 "USB flash emulating floppy" 和 "bootable CD emulating floppy").

更新

是的,问题正在发生变化,上面的一些答案不再适用。目前的问题是:

  • ds 在被使用它的 mov [BOOT_DRIVE], dl 指令使用之前未设置
  • mov ax,cs 不可能是对的。当 BIOS 启动代码时,它可以执行 jmp 0x0000:0x7C00jmp 0x07C0:0x0000(或任何组合),因此 cs 未设置为已知值并将未知值加载到 ax 帮不上什么忙。
  • mov ax,ds(紧接在 mov ax,cs 之后)没有设置 ds,而是加载 ax BIOS 碰巧留在 [=16= 中的值].我认为这条指令应该是 mov ds,ax(可能有效也可能无效,具体取决于使用的是哪个 computer/BIOS)
  • mov ax, dsmov ax, esmov ax, ss(紧跟在kernel:标签之后)有同样的问题(应该是mov ds, axmov es, ax,以及 mov ss, ax