最近我在尝试理解引导程序的工作原理。我正在使用nasm汇编语言编写我的加载器,并通过bochs和软盘镜像进行测试。
第一阶段和第二阶段的编译二进制文件通过复制合并成一个镜像。这个镜像正是我想要的。第一阶段代码有512字节(包括魔数)且可以成功加载,第二阶段代码有512字节且在第二个扇区。
但我认为我的问题是将扇区加载到内存并跳转到它。我的代码有什么问题吗?
Stage1.asm
我仔细搜索了一下,没有找到确切的方法来将扇区加载到RAM并跳转到它。甚至我的程序中也没有找到第二个扇区的Magicnumber。
如果只是地址计算错误,那就太好了。
更新: 当前源代码,标有死锁的行。出于纯粹的偏执狂,我将所有4个主寄存器都设置为0。
更新2: 再次更新版本。在设置寄存器和发出int 13h之间没有进行任何操作。
第一阶段和第二阶段的编译二进制文件通过复制合并成一个镜像。这个镜像正是我想要的。第一阶段代码有512字节(包括魔数)且可以成功加载,第二阶段代码有512字节且在第二个扇区。
但我认为我的问题是将扇区加载到内存并跳转到它。我的代码有什么问题吗?
Stage1.asm
BITS 16
start:
mov ax, 07C0h ; Set up 4K stack space after this bootloader
add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov ax, 07C0h ;Set data segment to where we're loaded
mov ds, ax
mov si,s_version
call print_string
; ## Load stage2
mov si,s_loading
call print_string
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
;read 2nd sector
mov ah,02h
mov al,1 ;read 1
mov ch,0 ;on track 0
mov cl,2 ;2nd sector
mov dh,0 ;head 1
mov dl,0 ;from floppy a
mov bx,09C0h;destination segment
mov es,bx
mov bx,0 ;destination offset
int 13h ;<-- Fails right here
mov si,s_sector
call print_string
;print number of read sectors
add ax, 48
mov ah, 0Eh
int 10h
mov al, 21
mov ah, 0Eh
int 10h
;print the sector's magicnumber (debugging purposes)
mov al, [09C0h+511]
int 10h
xor ax,ax
int 16h
mov si,s_jumping
call print_string
call word 09C0h:0000h
; #### print a string from si
print_string:
push ax
push bx
mov ah, 0Eh
.repeat:
lodsb
cmp al, 0
je .exit
int 10h
jmp .repeat
.exit:
pop bx
pop ax
ret
; ****
; #### define strings
s_version db 'VeOS 0.0.0.1',10,13,0
s_loading db 'Loading Stage2...',10,13,0
s_sector db 'Loading sector...',10,13,0
s_jumping db 'Passing control to Stage2.',10,13,0
; ****
;fillup with zeros
times 510-($-$$) db 0
;boot signature
dw 0xAA55
stage2.asm
BITS 16
start:
mov ax, 09C0h ; Set up 4K stack space after this bootloader
add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov ax, 09C0h ;Set data segment to where we're loaded
mov ds, ax
mov ah, 0Eh
mov al, 21 ;"!"
int 10h
mov ah, 00h
int 16h
jmp $
times 511-($-$$) db 0
;Magicnumber for debugging
db 0x41
我仔细搜索了一下,没有找到确切的方法来将扇区加载到RAM并跳转到它。甚至我的程序中也没有找到第二个扇区的Magicnumber。
如果只是地址计算错误,那就太好了。
更新: 当前源代码,标有死锁的行。出于纯粹的偏执狂,我将所有4个主寄存器都设置为0。
更新2: 再次更新版本。在设置寄存器和发出int 13h之间没有进行任何操作。
int 13h
命令之前却调用了print_string
函数。这可能会导致问题 :) - user786653bl
(http://www.ctyme.com/intr/rb-0106.htm),我有其他来源说`bh`值被忽略,所以我认为你也需要保存和恢复该寄存器。无论如何,如果你删除那个调用,它能正常工作吗? - user786653