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