為什麼要org 07c00h?
有很多人看了"自己動手寫作業系統"或其第二版這本書後對這一行提出疑問.
這個問題在書中作者的解釋是:
告訴編譯器,將來我們的這段程式要被載入到07c00處執行.
說實話"自己動手寫作業系統"這本書寫得確實不錯,我不是佩服作者的水平,而是作者的毅力,能把
這麼枯橾的知識系統地一步一步地親身實踐並寫成書(難度比我們隨意地寫BLOG要難千百倍吧),而且
作者盡自己的最大努力讓讀者能清楚明白.但是這幾句話,作者說得一點也不明白.當然我們相信作者
自己肯定明白,但這樣的表述"顯示出"不明白.
我們知道編譯器本身在彙編時對指令的地址計算的是相對位址.而對於開機磁區,一切只是從無生有的
階段,是按絕對位址執行.那麼對於用相對位址編譯的執行碼就要換算成絕對位址.
一般而言,"真實開始執行的開機磁區"都會固定裝載到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處開始編譯第一條指令,那麼下面的
相對位址被編譯載入後就正好和絕對位址吻合.