0

目前,我一直在关注 OS Dev 上的 BrokenThorn 系列,但遇到了一些问题。现在,作为本教程的一部分,我目前正在编写在第二阶段引导加载程序中加载的部分,但不幸的是,代码崩溃了。这是我认为麻烦的代码部分:

代码:

;browse root directory for binary image
     mov     ax, WORD [bpbRootEntries]; load loop counter, bpbRootEntries is the number of entries in the FAT table
     mov     di, 0x0000 ; because rep cmpsb compares the string in es:di to ds:si, and es holds 0x7e00 (the location of the FAT Table), I decided to set di to 0x0000
     mov     cx, 0x000B; eleven character name           
     lea     si, [ImageName] ;set si to the memory location of ImageName so ds:si points to ImageName          
 .LOOP:     
 rep  cmpsb     
      jz     LOAD_FAT
      add     di, 32                            ; queue next directory entry
      dec ax
      cmp ax, 0x0
 jne .LOOP

 jmp     FAILURE

这部分代码在 FAT 表中查找文件。但是,它无法找到它,因此崩溃。在此代码中,ImageName 是一个变量,其中包含值“KRNLDR SYS”。在我的软盘驱动器中,我的软盘驱动器中有一个名为“KRNLDR SYS”的文件(带有空格,而不是“KRNLDR.SYS”)。如果有人可以提供任何建议,那将是一个很大的帮助。

注意:我目前正在运行 64 位 Windows 7 PC

更新

在所有有用的评论之后,我更新了代码:

mov     ax, WORD [bpbRootEntries]             ; load loop counter
 mov     di, 0x0000                            ; locate first root entry
 mov     cx, 0x000B                            ; eleven character name               
 lea     si, [ImageName]                         ; image name to find            
 .LOOP:
      push di
      push si
      repe  cmpsb   
      pop di
      pop si
      jz     LOAD_FAT

      add     di, 32                            ; queue next directory entry

      dec ax
      or ax, ax
      jne .LOOP

      jmp     FAILURE

不幸的是,操作系统仍然无法找到该文件。

更新 2

这是我用来加载根目录表的代码:

     LOAD_ROOT:

 ; compute size of root directory and store in "cx"

      xor si, si

      mov     ax, 0x0020                           ; 32 byte directory entry
      mul     WORD [bpbRootEntries]                ; total size of directory
      div     WORD [bpbBytesPerSector]             ; sectors used by directory
      xchg    ax, cx

 ; compute location of root directory and store in "ax"

      mov     al, BYTE [bpbNumberOfFATs]            ; number of FATs
      mul     WORD [bpbSectorsPerFAT]               ; sectors used by FATs
      add     ax, WORD [bpbReservedSectors]         ; adjust for bootsector
      mov     WORD [datasector], ax                 ; base of root directory
      add     WORD [datasector], cx

 ; read root directory into memory (7C00:0200)

     mov   dx, 0x7e00
     mov   es, dx
     mov     bx, 0x0                             ; copy root dir above bootcode
     call    ReadSectors

谢谢!

4

3 回答 3

0

无论如何都会重复REP次数,并将设置为最后一次比较的结果。CMPSBCMPSB CXZF

  • 你需要一个REPE这里

即使使用REPE,REPE CMPSB也会修改两者DISI以便它们每个都指向比较最后一个字节之后的字节(假设DF设置为 UP)因此将 32 添加到DI CERTAINLY不会指向下一个 FAT 条目。

  • 您需要PUSH同时在之前DI和之后立即返回(这不会影响)SIREPE CMPSBPOPFLAGS

这样一来,似乎也DI没有改变,并且添加 32 是有效的。SI

通过技巧,OR AX,AX将设置ZF为相同CMP AX,0x0但更小、更快的指令。

于 2013-04-06T03:43:17.930 回答
0

我想我已经修好了(有点)。我使用了一个名为 WinHex 的十六进制编辑器,并在内存中找到文件的位置,并将其硬编码到程序中。它是暂时的,但在我可以开始用 C 为我的内核编程之前就足够了,我认为它会比汇编稍微简单一些。感谢大家的帮助!

于 2013-04-06T21:32:31.007 回答
0

我和你一样,但在 Linux(Brokenthorn OS 教程)上使用 Bochs。我创建了一个软盘映像并将其与 Bochs 一起使用。对我来说,Demo1.zip (Stage2) 中的代码有效。它从 Fat12 读取第二阶段加载程序。但是一开始它不起作用,因为当我将引导扇区复制到软盘映像时,软盘映像被截断了。请注意,我只在 Stage2.asm 中更改了要打印的文本。

https://sites.google.com/site/forthoperatingsystem/

于 2013-05-22T08:03:53.003 回答