Assembly 如何从扇区加载应用程序?
我正在创建自定义MBR,它必须加载存储在接下来32个扇区中的应用程序,除了加载应用程序之外,其他一切都可以正常工作,我不知道我做错了什么,所以如果有人知道如何修复它,请帮助我Assembly 如何从扇区加载应用程序?,assembly,nasm,x86-16,bootloader,Assembly,Nasm,X86 16,Bootloader,我正在创建自定义MBR,它必须加载存储在接下来32个扇区中的应用程序,除了加载应用程序之外,其他一切都可以正常工作,我不知道我做错了什么,所以如果有人知道如何修复它,请帮助我 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 - Seg
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:
org 0x7c00
第16位
内核:
;---设置段
异或ax,ax;AX=0
mov-ds,ax;DS=ES=0,因为我们使用0x7c00-段的组织主要问题是,当您调用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\u DRIVE],dl
指令使用之前未设置
mov-ax,cs
不可能正确。当BIOS启动代码时,它可以执行jmp 0x0000:0x7C00
或jmp 0x07C0:0x0000
(或任何组合),因此cs
不会设置为已知值,而将未知值加载到ax
也不会有多大帮助
mov-ax,ds
(紧接着mov-ax,cs
)不设置ds
,而是加载ax
,加载的值正好是BIOS在ds
中留下的值。我认为这条指令应该是一个mov-ds,ax
(可能有效,也可能无效,取决于使用的是哪台计算机/BIOS)
mov-ax,ds
,mov-ax,es
,和mov-ax,ss
(紧跟在内核之后:
标签)有相同的问题(应该是mov-ds,ax
,mov-es,ax
,和mov-ss,ax
主要问题是,当您调用int 0x13,ah=0x02
时,您需要在dl
中读取的设备的设备号。从中引导的设备号由dl
中的BIOS提供给您,但代码会覆盖它(以前的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\u DRIVE],dl
指令使用之前未设置
mov-ax,cs
不可能正确。当BIOS启动代码时,它可以执行jmp 0x0000:0x7C00
或jmp 0x07C0:0x0000
(或任何组合),因此cs
不会设置为已知值,而将未知值加载到ax
也不会有多大帮助
mov-ax,ds
(紧接着mov-ax,cs
)不设置ds
,而是加载ax
,加载的值正好是BIOS在ds
中留下的值。我认为这条指令应该是mov-ds,ax
(可能工作,也可能不工作,取决于使用的是哪台计算机/BIOS)
mov-ax,ds
,mov-ax,es
,一个