汇编语言 OS 引导加载程序 "using of nonexisting segment register 7" 错误
Assembly language OS boot loader "using of nonexisting segment register 7" error
我目前正在为一项大学作业做基础 OS。我正在使用 x86 汇编语言。
我似乎在切换到引导加载程序的第二阶段时遇到问题,导致当我尝试 运行 Bochs 中的应用程序时出现上述错误。根据我的测试,我认为该错误是应用程序未正确从内存中读取程序的结果,这可能是由于引导加载程序第一阶段的错误或 makefile 中的错误。我将在下面包括这两个:
引导加载程序的第一阶段:
BITS 16
ORG 7C00h
jmp Real_Mode_Start
%include "functions_16.asm"
Read_Failed:
mov si, boot_error
call Console_WriteLine_16
ret
Real_Mode_Start:
cli
xor ax, ax
mov ss, ax
mov sp, 4000h
mov ds, ax
mov si, boot_message
call Console_WriteLine_16
mov al, 5
mov bx, 9000h
mov ch, 0
mov dh, 0
mov dl, 0
mov cl, 2
int 13h
cmp al, 5
jne Read_Failed
jmp 9000h
hlt
; Data
boot_message: db 'MacOS Remastered' , 0
boot_error: db 'Boot Failed' , 0
times 510 - ($ - $$) db 0
dw 0AA55h
生成文件:
.DEFAULT_GOAL:=all
Imgname=MacRemastered
.SUFFIXES: .iso .img .bin .asm
%.bin: %.asm
nasm -w+all -f bin -o $@ $<
boot.bin: boot.asm functions_16.asm
boot2.bin: boot.asm functions_16.asm
$(Imgname).iso: boot.bin boot2.bin
cp floppy_image/$(Imgname).img $(Imgname).img
dd status=noxfer conv=notrunc if=boot.bin of=$(Imgname).img
dd status=noxfer conv=notrunc seek=1 if=boot2.bin of=$(Imgname).img
rm -rf cdiso
mkdir cdiso
cp $(Imgname).img cdiso/$(Imgname).img
mkisofs -o $(Imgname).iso -b $(Imgname).img cdiso/
all: $(Imgname).iso
clean:
rm -f boot.bin
rm -f boot2.bin
rm -f $(Imgname).img
rm -f $(Imgname).iso
rm -rf cdiso
如有任何帮助,我们将不胜感激。
您应该查看文档,因为 Int 13h/ah=2h. Ralf Brown's Interrupt guide 是 DOS 和 BIOS 中断的圣经。指南是这样说的:
DISK - READ SECTOR(S) INTO MEMORY
AH = 02h
AL = number of sectors to read (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5)
high two bits of cylinder (bits 6-7, hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
Return:
CF set on error
if AH = 11h (corrected ECC error), AL = burst length
CF clear if successful
AH = status (see #00234)
AL = number of sectors transferred (only valid if CF set for some BIOSes)
大多数问题都与您的磁盘读取有关:
- 您应该将 ES 设置为 0,因为缓冲区是由 ES:BX 指定的地址。
- 不要将 DL 设置为零。在传输到您的代码之前,BIOS 会将 DL 设置为引导驱动器。
- 您没有将 AH 设置为 2,它告诉
Int 13h
您想要进行磁盘读取。
- 而不是
cmp al, 5
jne Read_Failed
来测试磁盘错误,您可以检查进位标志 (CF)。在 Int 13h
之后用简单的 jc Read_Failed
替换这两行
我还建议使用 BOCHS 调试器进行 16 位实模式调试。当 BOCHS 调试器启动时,使用命令 b 0x7c00
在 0x7c00 处设置断点,然后使用命令 c
继续。那应该启动 BOCHS 启动并且应该在引导扇区的开头中断。基本命令:
help
命令列表
n
(下一个)
s
(步骤)
c
会一直持续到下一个断点。
b address
在地址处中断。即:b 0x7c00
我目前正在为一项大学作业做基础 OS。我正在使用 x86 汇编语言。 我似乎在切换到引导加载程序的第二阶段时遇到问题,导致当我尝试 运行 Bochs 中的应用程序时出现上述错误。根据我的测试,我认为该错误是应用程序未正确从内存中读取程序的结果,这可能是由于引导加载程序第一阶段的错误或 makefile 中的错误。我将在下面包括这两个:
引导加载程序的第一阶段:
BITS 16
ORG 7C00h
jmp Real_Mode_Start
%include "functions_16.asm"
Read_Failed:
mov si, boot_error
call Console_WriteLine_16
ret
Real_Mode_Start:
cli
xor ax, ax
mov ss, ax
mov sp, 4000h
mov ds, ax
mov si, boot_message
call Console_WriteLine_16
mov al, 5
mov bx, 9000h
mov ch, 0
mov dh, 0
mov dl, 0
mov cl, 2
int 13h
cmp al, 5
jne Read_Failed
jmp 9000h
hlt
; Data
boot_message: db 'MacOS Remastered' , 0
boot_error: db 'Boot Failed' , 0
times 510 - ($ - $$) db 0
dw 0AA55h
生成文件:
.DEFAULT_GOAL:=all
Imgname=MacRemastered
.SUFFIXES: .iso .img .bin .asm
%.bin: %.asm
nasm -w+all -f bin -o $@ $<
boot.bin: boot.asm functions_16.asm
boot2.bin: boot.asm functions_16.asm
$(Imgname).iso: boot.bin boot2.bin
cp floppy_image/$(Imgname).img $(Imgname).img
dd status=noxfer conv=notrunc if=boot.bin of=$(Imgname).img
dd status=noxfer conv=notrunc seek=1 if=boot2.bin of=$(Imgname).img
rm -rf cdiso
mkdir cdiso
cp $(Imgname).img cdiso/$(Imgname).img
mkisofs -o $(Imgname).iso -b $(Imgname).img cdiso/
all: $(Imgname).iso
clean:
rm -f boot.bin
rm -f boot2.bin
rm -f $(Imgname).img
rm -f $(Imgname).iso
rm -rf cdiso
如有任何帮助,我们将不胜感激。
您应该查看文档,因为 Int 13h/ah=2h. Ralf Brown's Interrupt guide 是 DOS 和 BIOS 中断的圣经。指南是这样说的:
DISK - READ SECTOR(S) INTO MEMORY
AH = 02h AL = number of sectors to read (must be nonzero) CH = low eight bits of cylinder number CL = sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only) DH = head number DL = drive number (bit 7 set for hard disk) ES:BX -> data buffer
Return:
CF set on error if AH = 11h (corrected ECC error), AL = burst length CF clear if successful AH = status (see #00234) AL = number of sectors transferred (only valid if CF set for some BIOSes)
大多数问题都与您的磁盘读取有关:
- 您应该将 ES 设置为 0,因为缓冲区是由 ES:BX 指定的地址。
- 不要将 DL 设置为零。在传输到您的代码之前,BIOS 会将 DL 设置为引导驱动器。
- 您没有将 AH 设置为 2,它告诉
Int 13h
您想要进行磁盘读取。 - 而不是
cmp al, 5
jne Read_Failed
来测试磁盘错误,您可以检查进位标志 (CF)。在Int 13h
之后用简单的
jc Read_Failed
替换这两行
我还建议使用 BOCHS 调试器进行 16 位实模式调试。当 BOCHS 调试器启动时,使用命令 b 0x7c00
在 0x7c00 处设置断点,然后使用命令 c
继续。那应该启动 BOCHS 启动并且应该在引导扇区的开头中断。基本命令:
help
命令列表n
(下一个)s
(步骤)c
会一直持续到下一个断点。b address
在地址处中断。即:b 0x7c00