2013-04-06 82 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/

相關問題