我写了一个简单的OS / bootloader,从磁盘加载4个额外的扇区,然后跳转到它们。但跳跃不起作用代码就挂了。
这是start.S文件
[BITS 16]
[ORG 0x7C00]
PROGRAM_SPACE equ 0x7E00
start:
mov bp, 0x7c00
mov sp, bp
call ReadDisk
mov bx, DiskSuccesString
call print
jmp 0x7E00
hang:
jmp hang
print:
push ax
push bx
mov ah,0x0e
.loop:
cmp word [bx], 0
je .exit
mov al,[bx]
int 0x10
inc bx
jmp .loop
.exit:
pop ax
pop bx
ret
ReadDisk:
mov ah, 0x01
mov bx, 0x7E00
mov al,4
mov dl,[BOOT_DISK]
mov ch,0x00
mov dh,0x00
mov cl,0x02
int 0x13
jc DiskError
ret
BOOT_DISK:
db 0
DiskError:
mov bx, DiskErrorString
call print
jmp $
DiskErrorString:
db 'Error while reading Disk ',0
DiskSuccesString:
db 'Succes!',0
times 510-($-$$) db 0 ; pad to 512 bytes and add MBR bootable signature
db 0x55
db 0xaa
这是kernel.S文件:
[BITS 16]
[ORG 0x7E00]
mov ax, 0x0000
mov ss, ax
mov sp, 0xFFFF
mov bx, msg
call print
jmp $
print:
push ax
push bx
mov ah,0x0e
.loop:
cmp word [bx], 0
je .exit
mov al,[bx]
int 0x10
inc bx
jmp .loop
.exit:
pop ax
pop bx
ret
msg:
db 'Welcome to PotatOS',0
times 2048-($-$$) db 0
这是我用来组装所有东西的文件:
#!/bin/zsh
rm start
rm kernel
nasm start.S
nasm kernel.S
cat start kernel > os.bin
qemu-system-x86_64 -enable-kvm -hda os.bin
我用了一个标签的地址,但取代了它的实际地址,但没有任何变化。
1条答案
按热度按时间bd1hkmkf1#
这里有很多未解决的问题
Bootstrap 从BIOS接收的唯一信息是DL寄存器中的磁盘标识。不能相信段寄存器包含合适的值。你必须自己设置这些,以便它们适合你的目标,特别是让它们雅阁
ORG 0x7C00
设置:始终与SS段寄存器一起更改SP堆栈指针寄存器。并且始终在SP寄存器之前直接修改SS寄存器:
mov [BOOT_DISK], dl
。您没有加载任何内容。0x 01是返回AH寄存器中磁盘状态的函数。可以从磁盘读取扇区的BIOS功能编号为0x 02。
看到
PROGRAM_SPACE equ 0x7E00
这行代码,可以这样写:jmp PROGRAM_SPACE
和mov bx, PROGRAM_SPACE
。你放在堆栈上的东西需要以相反的顺序出现!
您的消息是ASCIIZ字符串。它们的后缀是单个零字节。不要试图用一个字大小的操作来检测这个终结符。因为BIOS.Teletype函数也使用BX作为它的一些输入,你应该避免使用BX作为你的消息指针。使用其他地址寄存器之一。例如
cmp byte [si], 0
。重写start.S
不要忘记根据上面的内容重写kernel.S。
无论如何,再次更改SS:SP不是一个好主意。而且一定要始终选择一个偶数放入SP寄存器。0xFFFF是一个真实的糟糕的选择!