2015-07-10 121 views
15

我在PIC上看過this的帖子,似乎總是很好用PIC(無論何時它是exe /靜態/共享庫)。爲什麼不總是使用fpic(位置獨立代碼)?

那麼有什麼缺點?
有沒有例子闡述何時不使用PIC?

+1

PIC通常不能在Windows中使用,因爲在加載期間DLL地址是固定的。而且在x86 PIC中效率不如x86_64 –

回答

6

鏈接問題中接受的答案是非常簡單的,只會引出PIC和非PIC代碼之間不同的一個事物,即生成相對而非絕對的跳轉。

製作PIC代碼時,不僅是位置獨立的代碼,也是數據。並不是所有的代碼或數據都可以簡單地通過使用相對偏移量來尋址,它必須在加載時(庫/程序加載到內存中)或甚至在運行時解決。另外,使用相對尋址意味着CPU必須將相對偏移量轉換爲絕對地址,而不是由編譯器完成。

在帶虛擬內存的系統上,編譯器可以一勞永逸地完成這些相對地址分辨率時,通常不需要花費負載或運行時間。

+0

有沒有使用-fpic的情況,或者不使用fpic程序會崩潰? (編譯器是否爲這兩種情況生成合適的機器碼?) – Azil

+0

@Azil:它確實生成了正確的代碼。如果您正在構建共享庫(.so,.dll),您必須*使用PIC,否則不起作用。像Amiga這樣的機器的所有*代碼由於它們的架構而是PIC,但是那些代碼是在真正的* CPU(68k)上運行的,沒有受到它的影響。 ;-) – DevSolar

+0

因此,建立如此(dll)沒有PIC - 總是給編譯錯誤? – Azil

0

在某些體系結構上,包括x86,-fPIC生成很多加載/存儲數據的較差代碼(即函數調用)。雖然這對圖書館來說是可以忍受的,但對於可執行文件來說這是不可取的

amd64指令集(以及最近的gnu-x32 ABI)的主要賣點之一是增加了「PC相對加載/存儲」指令,從而解決了效率問題。

注意,硬化系統通常使-fPIE所有可執行文件,因爲它允許地址空間佈局隨機。

+0

這與函數調用沒有可比性,但它佔用一個寄存器。 – DevSolar

+0

@DevSolar uh,它絕對需要一個函數調用(儘管它可能會在第一次顯然後將其緩存在寄存器中)。它出現在反彙編中,使用'__x86.get_pc_thunk.cx'這樣的名字,顯然這個寄存器取決於當前使用的內容。 – o11c

+1

啊......我們的意思是一樣的。 「函數調用」是將偏移表的地址存入寄存器的技巧。保持緩存需要一個寄存器(如我所說),而不是緩存它使數據訪問需要一個函數調用(如你所說)。應該指出的是,這是x86體系結構的典型「醜陋點」之一;大多數(如果不是所有其他的CPU系列的話)在20世紀80年代允許適當的PC相對尋址... – DevSolar

相關問題