汇编语言OS引导加载程序"使用不存在的段寄存器7"错误

时间:2016-10-04 23:04:51

标签: assembly x86 nasm bootloader osdev

我目前正在为大学任务工作的基本操作系统。我正在使用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

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

您应该查看Int 13h/ah=2h的文档。 Ralf Brown's Interrupt guide是DOS和BIOS中断的圣经。指南说:

  

磁盘 - 将扇区读入存储器

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
     

返回:

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)。在jc Read_Failed
  • 之后,用简单的Int 13h替换这两行

我还建议使用 BOCHS 调试器进行16位实模式调试。当 BOCHS 调试器启动时,使用命令b 0x7c00在0x7c00处设置断点,然后使用命令c继续。这应该启动 BOCHS 启动,并应该在启动扇区的开始处中断。基本命令:

  • help获取命令列表
  • n(下一个)
  • s(步骤)
  • c将一直持续到下一个断点。
  • b address打破了地址。即:b 0x7c00