2012-05-07 49 views
3

我在寫一個引導加載程序和我下面教程工作提供此代碼:與建立分部困惑寄存器

main: 

;---------------------------------------------------- 
; code located at 0000:7C00, adjust segment registers 
;---------------------------------------------------- 

     cli      ; disable interrupts 
     mov  ax, 0x07C0    ; setup registers to point to our segment 
     mov  ds, ax 
     mov  es, ax 
     mov  fs, ax 
     mov  gs, ax 

;---------------------------------------------------- 
; create stack 
;---------------------------------------------------- 

     mov  ax, 0x0000    ; set the stack 
     mov  ss, ax 
     mov  sp, 0xFFFF 
     sti      ; restore interrupts 

我可能誤解的東西,但如果SS寄存器包含爲0x0000不會那意味着ds,es,fs和gs會疊加在一起?還有什麼是fs和gs寄存器的功能?另外,是由BIOS自動設置的cs段嗎?因爲它說代碼位於0000:7c00。另外,本教程永遠不會解釋爲什麼中斷被禁用。我在某處讀到中斷通常是禁用的,以避免死鎖。這是什麼意思,爲什麼會發生?

+0

只是一個觀察:你的代碼只能在386和更高的處理器上工作。 8086/8088/80286沒有'FS'和'GS'段寄存器。這可能是由設計,但我只是想指出。 –

回答

8

至少在理論上,是的,堆棧和代碼可能會重疊。他們不這麼做的原因很簡單:引導加載程序非常小,通常不會使用太多堆棧空間,所以堆棧永遠不會增長太多以覆蓋引導加載程序代碼的末尾。

就fs和gs而言,它們並沒有真正的用途。如果不考慮引導加載程序的代碼,可能會有人質疑它們是否被使用。如果他們被使用,它仍然有更多的問題,他們會用什麼

磁盤BIOS從磁盤加載一個扇區到07c00:0000h,並遠遠地跳到它。遠跳集合cs

您在設置堆棧時禁用中斷,因爲執行中斷(嘗試)將數據推入堆棧。如果尚未設置堆棧(包括SS和SP),通常甚至不知道數據(標記和返回地址)可能最終在內存中的什麼位置,或者可能覆蓋哪些其他數據。這通常是不可取的,因此至少在SS和SP都被設置之前,禁用中斷。

+0

除了古老的8088處理器(某些存在)之外,在指令持續期間更新ANY段寄存器期間,中斷標誌被關閉(臨時),直到* following *指令結束。如果更新了SS,然後按照一條更新SP的指令進行操作,那麼中斷將在兩者之間關閉。從286(及更高版本)開始,只有暫時關閉中斷標誌的寄存器纔是SS寄存器。 –

+0

由於遇到錯誤8088處理器的可能性,通常建議明確關閉中斷。 –

+0

你說_磁盤BIOS從磁盤加載一個扇區到07c00:0000h_。我認爲這是一個錯字,應該是_07c0:0000h_或_0000:7c00_(或任何等效的東西)。如果您不寫位置獨立代碼(即執行非遠程絕對JMP和CALL),則不能假定BIOS跳轉到設置正確的「CS」的代碼(因爲存在許多segment:offset組合)映射到相同的物理地址。如果你的代碼不是位置獨立的,那麼可以適當地在代碼設置CS中對FAR JMP執行一個標籤。 –