2013-04-06 53 views
0

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

代码:

;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

UPDATE

所有有用的意见后,我已经更新了代码:

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 

谢谢!

+0

你确信你的软盘文件系统实际上是FAT12,并且该文件确实是名为“KRNLDR SYS”? – duskwuff 2013-04-06 02:13:36

+0

因此,我在Windows中命名文件KRNLDR.SYS。在引导程序中,我正在搜索KRNLDR SYS(有2个空格)。但是,代码仍然无法找到该文件。我正在使用VFD创建虚拟软盘驱动器并对其进行格式化。我正在使用RawWrite将引导加载程序调整到扇区0,并在Windows中使用复制命令将KRNLDR加载到软盘。这个设置有问题吗? 在此先感谢您的帮助! – user1231745 2013-04-06 02:18:05

回答

0

CMPSBREP将重复CMPSBCX倍,无论和ZF将被设置为进行的最后比较的结果。

  • 你需要一个REPE这里

即使有REPEREPE CMPSB将修改两个DISI,使他们每个点的字节最后一个字节后相比,(让我们假设DF设置对于UP)因此,将32添加到DI某些将不会指向下一个FAT条目。

  • 您需要PUSHDISIREPE CMPSBPOP他们回来后立即(这不会影响FLAGS

这样一来,既不DI也不SI似乎被改变, 32的加入是有效的。

作为技巧,OR AX,AXZF设置为与CMP AX,0x0相同,但是是更小,更快的指令。

+0

正如您所建议的,我已更正了我的代码。新版本作为更新发布在原始问题中。谢谢! – user1231745 2013-04-06 12:57:22

+0

哦,太近了!是的 - 看到您转移修正案。好主意。现在你需要了解堆栈。这是一个LIFO缓冲区 - 后进先出。既然你按顺序按下了'DI'和'SI',那么你需要按照相反的顺序'POP',以便原始的'SI'被恢复到'SI'等等。就目前而言,原来的'SI' '和'DI'将被交换 - 因此您的匹配不会像您期望的那样... – Magoo 2013-04-06 13:05:44

+0

感谢您的快速回复!我没有意识到这一点,我已经在我的代码中纠正了这个问题。但是,该文件仍未找到。我认为问题在于我设置虚拟软盘的方式。我在我原来的问题的评论中描述了我的设置。你有可能看一看吗? – user1231745 2013-04-06 13:20:23

0

我想我已经修复它(有点)。我使用了一个名为WinHex的十六进制编辑器,并将文件的位置定位到内存中,并将其硬编码到程序中。它是暂时的,但直到我可以开始用C语言编写内核为止,我认为这会比Assembly更简单。感谢所有人的帮助!

0

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

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

相关问题