2012-04-24 41 views
2

最近IM學習如何寫一個引導扇區,這裏是我學習的完整代碼:什麼在組件中使用「組織XXXX」的

org 07c00h 
    mov ax, cs 
    mov ds, ax 
    mov es, ax 
    call DispStr 
    jmp $ 

DispStr: 
    mov ax, BootMessage 
    mov bp, ax 
    mov cx, 16 
    mov ax, 01301h 
    mov bx, 000ch 
    mov dl, 0 
    int 10h 
    ret 

BootMessage: db "Hello, OS!" 
times 510-($-$$) db 0 

dw 0xaa55 

一個非常簡單的代碼,如果你知道如何引導一個系統。其結果是在屏幕上顯示的行Hello OS!,我不知道的唯一事情就是第一行:org 07c00h,這本書告訴我,這行代碼讓編譯器找到該地址爲7C00h處地方,但對此的解釋是非常模棱兩可,我真的不知道這裏有什麼用處。 org 07c00h在這裏做什麼?我試圖刪除行,並使用NASM創建bin文件,然後使用Bochs的引導bin文件。與上一個沒什麼不同:「你好OS!」也顯示在屏幕上。我可以說第一行在這裏什麼都不做?在世界上使用org xxxx是什麼?

+0

這意味着這本書所說的。如果你不理解它,你應該再次查看基礎知識。特別是,你需要了解記憶是如何工作的。 – 2012-04-24 15:52:11

+3

正如[nasm手冊](http://www.nasm.us/doc/nasmdoc7.html#section-7.1.1)所述:「ORG指令的功能是指定NASM將承擔的起始地址程序從裝入內存時開始。「即你正在告訴彙編程序自己無法弄懂的東西:程序將在什麼地址加載。 – user786653 2012-04-24 16:32:13

+0

@Karl:你應該首先明白什麼是幫助和善良,以及如何回答人們去啓發他們,而不是隻是唾棄。 – SasQ 2012-06-17 21:47:21

回答

3

這是,你必須一步到位的彙編器和連接器。該組織指出哪些告訴連接(在這種情況下往往是相同的程序),其中物理內存空間把下面的代碼彙編。當您使用C編譯器或其他一些高級語言編譯器,你經常有單獨的編譯和鏈接步驟(儘管編譯器通常需要調用鏈接爲你在幕後)。源被編譯爲位置無關的目標文件,其中一些指令在鏈接步驟中未實現。鏈接器從描述內存空間的用戶那裏獲取對象和鏈接器腳本或信息,然後從那裏編碼該內存空間的指令。

User786653對它進行了很好的設置,它告訴彙編程序它無法自行確定這些指令將要存在的內存空間/地址,以防需要在指令中進行位置相關編碼。如果它是一個包含地址信息的二進制文件,例如elf,srec,ihex等,它也會在輸出二進制文件中使用該信息。

+0

thx,但是'org 7c00h'是什麼意思?段是7c00h,或者偏移量是7c00h?我可以使用哪個工具來檢測地址? – Searene 2012-04-25 07:53:00

+0

好吧,使用bochs調試器,我發現0x7c00h被添加到偏移地址部分,如果沒有第一行'org 07c00h',系統會加載錯誤的字符串'BootMessage',thx很多。我學到了很多。 – Searene 2012-04-25 08:13:19

2

彙編程序正在將您的sorce代碼的每一行轉換爲處理器指令並生成這些指令一個接一個地依次輸入到輸出二進制文件中。這樣做,他擁有一個內部計數器,它可以從0開始計數任何此類指令的當前地址。

如果你正在裝配一個正常的程序,這些指令最終會在某個目標文件的代碼段中出現,只有空白的地址插槽,然後由鏈接器填寫正確的地址,所以它不是一個問題。

但是,當您組裝一個沒有任何部分,重定位和其他格式的平面二進制文件時,只需要原始機器指令,那麼彙編器就沒有關於您的標籤在哪裏指示數據地址以及什麼是地址的信息。因此,例如,當您有指令mov si, someLabel時,彙編程序只能計算從二進制文件開始處的0開始的此標籤的偏移量。也就是說,它假定您的代碼將位於您的代碼段中偏移量0開始的內存中。

如果不是這樣,並且您希望機器指令在內存中從其他地址開始,例如。 7C00,那麼你需要通過在你的源代碼開始處寫入org 0x7C00來告訴彙編程序你的程序的起始地址是7C00。該指令告訴彙編器它應該從7C00而不是從0啓動它的內部地址計數器。其結果是,在這樣的程序中使用的所有地址將通過7C00偏移。彙編器只需將7C00添加到爲每個標籤計算的每個地址。效果就好像標籤位於內存中的地址,比如7C487C00 + 48)而不是僅僅00480000 + 48),無論它是從二進制映像文件的開頭只偏移了48個字節(它之後在偏移量7C00加載將給出正確的地址)。

至於你的其他問題:7C00是引導程序的物理地址。您可以用不同的方式將此物理地址表示爲邏輯地址(段:偏移量),因爲段重疊(下一個段在前一個段之後開始16個字節(以十六進制表示的10))。例如,您可以使用邏輯地址0000:7C00這是最簡單的配置:您從RAM的開始處開始使用段0,並從該0開始偏移7C00。或者,您可以使用邏輯地址07C0:0000,即7C0 th段。請記住,段的起始位置彼此相距16個字節?所以你簡單地乘以這7C01016十進制),你得到7C00 - 見?這是在你的十六進制地址右移一個位置的問題! :-)現在你只需添加你的偏移量,這次是0,所以它的物理上仍然是7C00。段07C0中的字節0開始於內存中的7C00

當然,你也可以使用更復雜的地址一樣,例如,0234:58C0,這意味着該段開始於2340當你添加58C0抵消它,你會得到7C00再次:-)但這樣做可能會令人困惑。這一切都取決於你需要什麼配置。如果你想考慮7C00物理地址作爲你的段的開始,只需使用段07C0,你的第一條指令將在偏移0,所以你不需要把org指令,或者你可以把org 0然後。但是如果你需要在7C00地址下面讀取/寫入一些數據(例如,查看BIOS數據或查看中斷向量),然後使用段0和偏移量7C00這意味着您的第一條指令(二進制文件中的第0個字節)將會位於內存中的7C00物理地址;那麼您必須從上述原因中添加org 0x7C00指令。