【发布时间】:2015-09-29 10:20:11
【问题描述】:
为了学习,我已经研究过制作一个小型操作系统,现在正在使用引导加载程序。我希望能够使用int 0x13 从软盘驱动器读取扇区,将它们放入内存,然后跳转到该代码。这是我目前所拥有的:
org 0x7c00
bits 16
main:
call setup_segments
mov ah, 2 ; function
mov al, 1 ; num of sectors
mov ch, 1 ; cylinder
mov cl, 2 ; sector
mov dh, 0 ; head
mov dl, 0 ; drive
mov bx, 0x1000 ;
mov es, bx ; dest (segment)
mov bx, 0 ; dest (offset)
int 0x13 ; BIOS Drive Interrupt
jmp 0x1000:0 ; jump to loaded code
times 510 - ($-$$) db 0 ; fluff up program to 510 B
dw 0xAA55 ; boot loader signature
LoadTarget: ; Print Message, Get Key Press, Reboot
jmp new_main
Greeting: db "Hello, welcome to the bestest bootloader there ever was!", 0
Prompt: db "Press any key to reboot...", 0
Println:
lodsb ; al <-- [ds:si], si++
or al, al ; needed for jump ?
jz PrintNwl ; if null is found print '\r\n'
mov ah, 0x0e ; function
mov bh, 0 ; page number ?
mov bl, 7 ; text attribute ?
int 0x10 ; BIOS Interrupt
jmp Println
PrintNwl: ; print \r\n
; print \r
mov ah, 0x0e ; function
mov al, 13 ; char (carriage return)
mov bh, 0 ; page number ?
mov bl, 7 ; text attribute ?
int 0x10
; print \n
mov ah, 0x0e ; function
mov al, 20 ; char (line feed)
mov bh, 0 ; page number ?
mov bl, 7 ; text attribute ?
int 0x10
ret ; return
GetKeyPress:
mov si, Prompt ; load prompt
call Println ; print prompt
xor ah, ah ; clear ah
int 0x16 ; BIOS Keyboard Service
ret ; return
setup_segments:
cli ;Clear interrupts
;Setup stack segments
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
sti ;Enable interrupts
ret
new_main:
call setup_segments
mov si, Greeting ; load greeting
call Println ; print greeting
call GetKeyPress ; wait for key press
jmp 0xffff:0 ; jump to reboot address
times 1024 - ($-$$) db 0 ; fluff up sector
我想将LoadTarget之后的扇区加载到地址0x1000:0中,然后跳转到它。到目前为止,我只是得到一个空白屏幕。我觉得这个错误介于main 和times 510 - ($-$$) db 0 之间。也许我只是没有得到寄存器的值吗?请帮忙!谢谢
【问题讨论】:
-
既然
setup_segments已经是第二个扇区,如果它还没有加载,你希望它如何工作?此外,设置ss而不设置sp是非常糟糕的做法,您无法知道堆栈将在哪里。 -
@Jester 哦,是的,没想到这一点;)。另外我应该在哪里设置
sp?
标签: assembly x86 nasm boot bios