引导程序为什么要org 07c00h
WHY
我們知道編譯器本身在匯編時對指令的地址計算的是相對地址。而對于引導扇區,一切只是從無生有的
階段,是按絕對地址執行,那么對于用相對地址編譯的執行碼就要換算成絕對地址。
一般而言,“真實開始執行的引導扇區"都會固定裝載到07c00處,主意這句話是說一個真正的引導扇區。
對于硬盤上,會有一個主引導扇區,然后由它來控制和其它引導扇區,比如grub控制windows,linux等。
那么這個主引導扇區會加載在0600h處,當選擇其它可引導扇區時再將真正的可引導扇區加載到07c00h。
所以一般而言真正的可引導扇區都裝載到07c00h處。
因為編譯器在編譯時的地址是從第一行開始用0000h開始相對計算的。假如我們定義一個str: dw?"zxy"
它的相對地址是0100h,如果我們mov ax str那么就是將0100h傳給ax,這在編譯后的執行碼中是固定的。
而引導扇區是使用絕對地址執行的,指令從07c00h處開始執行,那么訪問0100h絕對是錯誤的訪問。真實
的絕對地址是07c00h+0100h,所以如果你不寫org 07c00h,把mov ax str寫成mov ax str+07c00h對于
傳址操作是一樣的目的。對于作者的那段程序可以去掉第一行的org 07c00h.把"mov ax,BootMessage"
改成"mov ax,BootMessage+07c00h",效果是一樣的。
但是如果有大量的傳址操作,那就要在每個地方都要+07c00h,那是一件非常頭痛的事。
所以在第一行加上org 07c00h只是讓編譯器從相對地址org 07c00h處開始編譯第一條指令,那么下面的
相對地址被編譯加載后就正好和絕對地址吻合。
另一篇文章的解釋(其實差不多)
簡單說來,該指令用來修正該指令以后出現的(變量/標志的)內存地址,也就是說如果有ORG 0x12345h,那么在該指令以后的變量的地址將被修正為0x12345+old_addr。
對于DOS中的COM文件,在被DOS裝載進內存后,系統會在內存的CS:0000 – CS:0100區域創建一個PSP,這里存放了一些系統所需的信息,比如通過
引導程序為什么要org 07c00h
命令行所傳遞的參數等,COM文件的代碼將被裝載到CS:0100 – CS:XXXX的內存區域,所以說如果COM代碼中不通過使用ORG 100h來進行修正的話,該段中的變量將不能被正確訪問,這時,對改變量的訪問將導致PSP中的數據被訪問了,從而得不到預期的結果。對于EXE文件,其所采用的方式可能就不一樣了,具體是怎樣的,目前還不知道。。。對于一些引導程序,這些程序將被BIOS裝載到內存中的指定地方,通常為0000:7C00,這跟DOS裝載COM文件的機制是一樣的,只不過DOS是將COM文件的代碼裝載到CS:0100處。所以在,引導程序的匯編代碼中,需要指定ORG 7C00H來對代碼中的變量的內存地址進行修正。
如:
ORG 7C00H
msg? db ‘HELLO WORLD’,0
MOV DX, OFFSET msg
在有ORG 7C00H的情況下,MOV DX, OFFSET msg對應的指令為MOV DX,7C4B(這里4B為msg在當前數據段中的偏移位置)如果沒有ORG 7C00H,那么真正被執行的指令將為MOV SI,004B,試想,BIOS已經將該代碼裝載到0000:7C00處,0000:0000 – 0000:7C00之間的數據可能為其他更重要的數據,如果使用004B就得不到我們所要訪問字符串msg,因為我們的字符串被BIOS放在7C4B這里了,所以我們的程序(最終由編譯器來完成)就必須迎合BIOS的這種規定了。
計算機接電啟動后,先運行存儲在ROM中BIOS程序,然后BIOS程序將 系統引導程序的開始位置 加載到內存:0000:7C00的位置
總結
以上是生活随笔為你收集整理的引导程序为什么要org 07c00h的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 保护模式
- 下一篇: 保护模式下寻址(易懂)