歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux0.00 ld鏈接時為什麼加上-Ttext 0

匯編程序會經過二次遍歷,有些符號引用會被標記為可重定位,在編譯好後他們的偏移值是其在代碼內部的偏移值,即LC計數器的值,當載入內存運行時,由於起始加載地址會不確定,所以會在加載後把代碼段所在的內存起始地址加到符號引用原有的偏移上,這就叫重定位。比如一個jmp abc會跳到代碼段內部偏移10的地方,但是代碼被加載到內存偏移1000,所以實際上那個abc標號偏移10的地方在實際的內存裡面偏移是1010,所以再繼續往abc(偏移10)跳會出問題,故而給abc的偏移10加上加載處起始地址1000,得出1010,這樣jmp 1010就執行正確了,達到重定位的目的。

不加這個選項,默認ld會給代碼內所有的偏移加上0x08048000,導致head.s代碼內很多16位寄存器盛不開這個大數,報錯。而使用-Ttext 0會告訴ld給代碼內所有的偏移加上0,這樣相當於還是保留了符號引用的原值(即代碼內偏移量——LC)。當head程序被boot加載到內存0地址處運行時,真實的內存引用計算方法是代碼原偏移+0,也就還是原偏移,而程序裡的符號引用的偏移恰好依然是原偏移,所以內存引用正確。

對於一般的匯編程序在OS存在的情況下ld鏈接,默認的都是把代碼段原偏移加上0x08048000然後做成elf可執行文件,因為OS的加載器把elf代碼加載到0x08048000處運行,而非0x0處,這樣的話內存實際引用是原偏移+0x08048000,而代碼段內的符號引用確實已經被改為了原偏移+0x08048000,故而引用正確。

由此來看,我們的手動用-Ttext 0把代碼內部符號引用的偏移加上0,然後又把代碼手動加載到0處運行,正好是起到了加載器的作用。故,一切正常。

Copyright © Linux教程網 All Rights Reserved