我正在编写小型操作系统 - 用于练习.我从bootloader开始.
我想创建一个以16位实模式运行的小命令系统(现在).
我创建了重置驱动器的bootloader,然后在bootloader之后加载扇区.
问题是因为jmp功能后没有任何实际发生.
我不想尝试在0x7E00加载下一个扇区(我不完全确定如何使用es:bx指向地址,这可能是一个问题,我相信它的地址:偏移),就在引导加载程序之后.
这是代码:
;
; SECTOR 0x0
;
;dl is number of harddrive where is bootloader
org 0x7C00
bits 16
;reset hard drive
xor ah,ah
int 0x13
;read sectors
clc
mov bx,0x7E00
mov es,bx
xor bx,bx
mov ah,0x02 ;function
mov al,0x1 ;sectors to read
mov ch,0x0 ;tracks
mov cl,0x1 ;sector
mov dh,0x0 ;head
int 0x13
;if not readed jmp to error
jc error
;jump to 0x7E00 - executed only if loaded
jmp 0x7E00 …Run Code Online (Sandbox Code Playgroud) 我一直在开发一个简单的引导加载程序,并且在某些环境中偶然发现问题,这些环境中的指令不起作用:
mov si, call_tbl ; SI=Call table pointer
call [call_tbl] ; Call print_char using near indirect absolute call
; via memory operand
call [ds:call_tbl] ; Call print_char using near indirect absolute call
; via memory operand w/segment override
call near [si] ; Call print_char using near indirect absolute call
; via register
Run Code Online (Sandbox Code Playgroud)
这些中的每一个碰巧涉及间接接近CALL到绝对存储器偏移.我发现如果我使用类似的JMP表,我会遇到问题.相对的呼叫和跳转似乎没有受到影响.像这样的代码有效:
call print_char
Run Code Online (Sandbox Code Playgroud)
我已经通过海报讨论了Stackoverflow上提出的建议,讨论了编写引导加载程序的注意事项.特别是我看到这个Stackoverflow回答了一般的Bootloader技巧.第一个提示是:
- 当BIOS跳转到您的代码时,您不能依赖具有有效或预期值的CS,DS,ES,SS,SP寄存器.应在引导加载程序启动时正确设置它们.您只能保证将从物理地址0x07c00加载并运行引导加载程序,并将引导驱动器号加载到DL寄存器中. …
我正在尝试制作一个适用于两种架构的引导加载程序:x86 和 PDP-11。主操作系统是为 PDP-11 兼容机器编写的,但从 x86 启动也应该可以工作,启动模拟器。
AFAIK,如果最后两个字节是, x86 加载第一个磁盘扇区0x7c00并跳转到那里。相反,如果第一个命令是且最后两个字节是 ,则 PDP-11 兼容机将第一个扇区加载到(八进制)并执行它。然而,由于一些硬件细节的原因,加载的数据实际上是颠倒的——例如,x86 读取的数据,另一台机器读取的数据。在这种情况下,这在某种程度上是一个功能,因为如果我制作最后两个字节,它们将适用于两台机器。0x55 0xaa0o20000NOP0xaa 0x550x120xed0x55 0xaa
总之,PDP-11兼容机需要前两个字节包含NOP命令,即0o000240,或0x00a0。数据被反转,因此 x86 实际上会读取0xff5f。
0x5f是 x86 中的真实命令。不幸的是,它是pop di. AFAIK,sp和ss值都没有指定,所以这个命令读取谁知道什么。
我的问题是:
0x0000:0x0000or 0xffff:0xffff?ss:sp指向读取不安全的内存映射硬件寄存器?如果是的话,如果我读了它们,会发生什么更糟糕的事情?我不想意外损坏笔记本电脑。ss:sp指向不可用的内存,即可能pop di触发总线错误?如果是,BIOS 将如何从中恢复,即它将重新启动、显示消息或执行其他操作?