【问题标题】:How to load application from sectors?如何从扇区加载应用程序?
【发布时间】:2018-10-19 19:14:38
【问题描述】:

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

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:

【问题讨论】:

  • 嗯,我首先想到的是设置细分。你做mov sp, 0x7c00,你说移动0x7c00到sp。但是你也做mov ax, ds 并且你希望这会将 ax 移到 ds?您认为mov 会朝哪个方向移动?你也永远不会确切地说出了什么问题。不要强迫我们运行您的代码来试图了解您的问题。
  • 你把buffer:放错地方了。应该在dw 0xAA55之后
  • 很有趣,但它不起作用,没有任何改变
  • 我可以告诉你,反汇编 victoria.com(二进制文件)不会走得太远。我不确定您从哪里获得该代码,但即使将其加载到内存中,它也不会按预期运行。代码看起来很适合加载,但我认为它根本不会像您期望的那样运行 victoria.com。
  • 如果您将buffer: 放在dw 0xAA55 行之后,则此代码是正确的。问题是Victoria.com 不包含可以按照加载方式正常运行的代码。

标签: assembly nasm x86-16 bootloader


【解决方案1】:

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

还有多个其他问题。段寄存器设置不正确(例如mov ax,ds而不是mov ds,ax)并且没有设置在正确的位置(应该在使用段之前完成 - 例如在ds段被使用之前mov al,[si] 代码中的指令打印字符串)。你不能仅仅假设int 0x13, ah = 0x02 在没有检查错误的情况下工作(如果有错误,你应该显示很好的“最终用户可读”错误消息,让用户有希望弄清楚他们可以做些什么来修复问题)。

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

更新

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

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

【讨论】:

    猜你喜欢
    • 2013-08-24
    • 2012-03-29
    • 1970-01-01
    • 2012-07-25
    • 2017-01-24
    • 2012-02-03
    • 2012-04-09
    • 2014-05-17
    • 1970-01-01
    相关资源
    最近更新 更多