2013-04-17 51 views
1

可以說我有一個A.c文件並將其編譯爲A.o文件。 的A.c文件如下:一起內存共享.o文件

int a; 
void add(void) 
{ 
} 

A.o文件與B.o形式的1.exe文件。 A.o文件與C.o一起構成2.exe文件。

,如果我在同一時間運行1.exe2.exe我的問題,將在aadd()地址是這兩個.exe文件一樣嗎?換句話說,內存中有兩個A.o還是隻有一個?

回答

1

您在內存中沒有任何重新定位的對象文件。

我猜你有一個Linux系統。如果在Windows上,原則保持不變,但細節不同。

接頭(稱爲建立兩者1.exe2.exe)生成可執行ELF文件(由若干段的,特別是所謂的"text" segment爲機器代碼和只讀恆定的數據,並且"data" segment爲可變數據)。啓動該程序的系統調用是內存映射ELF文件的幾個段(幾乎與系統調用的一些mmap(2)一樣)。

請注意,對於Linux可執行文件使用.exe文件後綴很混亂且不常見。通常,Linux可執行文件根本沒有後綴,並以小寫字母開頭。

鏈接器已複製並將兩個A.o文件重新分配到不同的東西(因爲relocation)。所以通常情況下,aadd的地址在1.exe2.exe中是不同的,處理它們的機器指令也是如此。

每個process都有它自己的address space(可以用例如mmap(2)系統調用改變)。輸入cat /proc/1234/maps來了解pid 1234進程的地址空間。也試試cat /proc/self/maps來獲取運行該進程的地址空間cat

如果不是A.o對象你有共享對象(或動態庫)libA.so它的一些(mmap -ed)段將共享(和其他人將使用copy on write技術),以及一些搬遷發生在動態鏈接時間(例如,在dlopen期間,如果它是插件)。

請參閱Levine's book on Linkers and Loaders

+0

任何數據損壞? – rubenvb

+0

由於原始海報使用'.exe'後綴 –

+0

啊,那麼OP可能在Windows上使用GCC,所有關於'mmap'和ELF的東西都是不相關的。 – rubenvb

1

aadd的地址將不一樣。你有兩個進程,因此在這個例子中有兩個內存拷貝。

0

它依賴於鏈接....默認情況下,鏈接總是動態的,所以當你加載兩個exe文件到內存中的文件A.o將表現爲可重入函數,並且它的唯一一個實例將在這兩個exe文件共享的內存中...

其類似printf函數...有太多printf任何diff diff文件,但一次只有一個實例運行在內存...

入函數不應該送你爲什麼要使用該.exe後綴,美必須照顧