首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NASM简单引导加载程序不会使用INT 13H加载扇区

NASM简单引导加载程序不会使用INT 13H加载扇区
EN

Stack Overflow用户
提问于 2020-09-08 03:35:25
回答 1查看 73关注 0票数 1

如果我直接从引导扇区运行,那么到目前为止我做的任何事情都可以正常工作,但是我就是不能从引导扇区直接加载任何东西。我尝试了许多不同的驱动器编号: 0x00 --> 0x03、0x80 --> 0x83。此外,这基本上与ep.4 of Queso Fuego's OSDEV series完全相同

代码语言:javascript
运行
复制
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 10HINT 13H维基百科页面,我认为它们可能有助于了解我正在尝试对寄存器做什么。提前谢谢你!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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上的中断表)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63783318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档