如果我直接从引导扇区运行,那么到目前为止我做的任何事情都可以正常工作,但是我就是不能从引导扇区直接加载任何东西。我尝试了许多不同的驱动器编号: 0x00 --> 0x03、0x80 --> 0x83。此外,这基本上与ep.4 of Queso Fuego's OSDEV series完全相同
org 0x7c00
bits 16
mov bx, 0x1000
mov es, bx
mov bx, 0x0000
mov dh, 0x00
mov dl, 0x00
mov ch, 0x00
mov cl, 0x02
read_disk:
mov ah, 0x02
mov al, 0x01
int 0x13
jc read_disk
mov ax, 0x1000
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x1000
times 510-($-$$) db 0
dw 0xaa55
mov ah, 0x00
mov al, 0x01
int 0x10
mov ah, 0x0b
mov bh, 0x00
mov bl, 0x01
int 0x10
mov si, testString
call print_string
hlt
print_string:
mov ah, 0x0e
mov bh, 0x00
mov bl, 0x07
print_char:
mov al, [si]
cmp al, 0
je end_print
int 0x10
add si, 1
jmp print_char
end_print:
ret
testString: db 'Kernel Booted!', 0xa, 0xd, 0
times 1024-($-$$) db 0任何建议都会非常感谢,我已经坚持了好几天了。我一直在使用INT 10H和INT 13H维基百科页面,我认为它们可能有助于了解我正在尝试对寄存器做什么。提前谢谢你!
发布于 2020-09-08 04:39:58
主要问题可能是"jmp 0x1000",它(取决于CS是什么)可能跳到0x0000:0x1000 (物理地址0x00001000),但可能跳到0x007C0:0x10000 (物理地址0x00008C00)或其他地方。您在"0x1000:0x0000“(或物理地址0x00010000)加载了扇区,因此跳转几乎不可能是正确的。相反,您需要像"jmp 0x1000:0x0000“这样的”远跳转“来设置CS和IP (而不只是设置IP并将CS保留为BIOS想要的任何值)。
其他问题包括:
a)要使用的正确设备号(在dl中,当您要求BIOS加载扇区时)是BIOS告诉您的正确设备号(在启动代码时在dl中)
b) BIOS可能将堆栈(SS:SP)放在几乎任何位置,包括将堆栈放在加载扇区时覆盖的相同地址。这意味着加载一个扇区可能会丢弃堆栈(当BIOS正在使用它时),并导致BIOS崩溃。在对任何其他内存执行任何操作之前,您需要将SS:SP设置为不会导致问题的内容。请注意,您的代码设置了SS而没有设置SP (这也是一个错误),而且做得太晚了。
c)如果像"int 0x13,ah=0x02“这样的基本输入输出系统功能失败,基本输入输出系统会告诉你一个错误代码(在ah中)。使用错误代码来通知用户哪里出了问题是非常重要的,这样他们就可以修复问题(例如,这样他们就可以确定是软件问题还是硬件问题),而不是被无法启动的计算机卡住,也不知道原因。这也可以帮助开发人员(您)找到并修复bug。这意味着使用错误代码查找错误字符串,然后打印该错误字符串。不幸的是,不可能在512字节内获得良好的错误处理(字符串占用太多空间);但您可以轻松地在512字节内进行“总比没有好”的错误处理(例如,在通用字符串的末尾打印一个原始的十六进制代码,比如"ERROR: Failed to load sector, BIOS error code 0x02“后跟"Boot aborted")。
d)软盘是出了名的不可靠;因此标准做法是在假定错误有效之前重试(至少)3次,同时要求BIOS在两次重试之间重置磁盘系统("int 0x13,ah=0x00")。
e) hlt指令不会永远停止中央处理器-它只是要求中央处理器等待,直到IRQ发生(对于hlt,仅来自定时器的IRQ通常每秒发生18.2次)。这意味着CPU不会在你的hlt停止,它会在hlt之后继续执行代码(可能会导致你的代码随机打印垃圾,然后“返回到未定义的地址,因为例程没有正常调用”,很可能会崩溃)。为了解决这个问题,使用一个循环;比如".die:","hlt“,然后是"jmp .die”。
f)软盘已经过时大约20年了。对于硬盘驱动器,您必须处理某种类型的分区系统,并且引导加载程序不能/不能从磁盘的第一个扇区开始。相反,您的引导加载程序将从分区的第一个扇区开始。
g) BIOS也应被认为已过时(由UEFI取代)。尽管BIOS现在仍然存在于旧计算机上,但当您完成操作系统编写后,它将不再存在于旧计算机上。出于这个原因,最好了解UEFI (而不必费心学习BIOS)。
注意:如果您使用的是BIOS,那么最好依靠Ralph Brown的中断列表来获得BIOS功能的文档。您可以在http://www.ctyme.com/rbrown.htm上找到它(但您通常需要http://www.ctyme.com/intr/int.htm上的中断表)。
https://stackoverflow.com/questions/63783318
复制相似问题