如何在Assembly中搜索FAT12系统中的文件

时间:2013-04-06 02:11:04

标签: assembly operating-system

目前,我一直关注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

谢谢!

3 个答案:

答案 0 :(得分:0)

REP上的CMPSB将重复CMPSB CX次,而ZF将设置为最后一次比较的结果。< / p>

  • 您需要REPE此处

即使使用REPEREPE CMPSB也会同时修改DISI,以便它们每个都指向比较最后一个字节后的字节(让我们假设{ {1}}设置为UP)因此,向DF CERTAINLY 添加32将不会指向下一个FAT条目。

  • DI之前PUSHDI之前SIREPE CMPSB之后需要POP {这不会影响{{1} }})

这样,FLAGSDI似乎都没有改变,32的添加也是有效的。

通过技巧,SI会将OR AX,AX设置为与ZF相同,但它是更小,更快的指令。

答案 1 :(得分:0)

我想我已经修好了(有点)。我使用名为WinHex的Hex编辑器,将文件的位置定位在内存中,并将其硬编码到程序中。它是临时的,但只要我能在C中为我的内核开始编程就足够了,我认为它比Assembly更简单。感谢大家的帮助!

答案 2 :(得分:0)

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

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