-
1 # 三袋大菠蘿
-
2 # 枝枝葉葉
這個 硬體上 的 mmu,以及作業系統 支援的 多程序,虛擬地址空間,就是起這個作用,解決這個問題的 。這樣,兩個程序,有兩個獨立的地址空間,相互不會干擾,雖然有可能引用了同一地址,但經過每個 程序的 頁表 對映 以後,對映到 不同的 物理地址 上去。這樣的例子,典型的有linux 作業系統
某些實時 作業系統,不支援虛擬地址空間,所以,所有在系統上執行的 程式,必須一次性編譯好,這樣才不會有地址方面的衝突,這樣的系統,不支援作業系統啟動以後,再載入應用程式 。沒有mmu 的 cpu 都採用這樣的 作業系統,比如ecos
-
3 # 味冷
把一個程式自己的程式碼、資料、堆疊看成一塊完整的磚頭。編譯器就是造磚機,安排好這一塊磚內部的結構。
裸奔的系統就這一塊磚,不會發生相互覆蓋的矛盾。
如果跑多工,磚頭就多了。但這時通常會引入作業系統來管理磚頭。堆砌磚頭時會給每塊磚頭不一樣的起始座標,確保不發生兩塊磚頭佔一個空間的情況。
早期的dos作業系統規定每塊磚頭高度不超過1M。編譯器做出來的每塊磚內部都是用偏移地址0000h—ffffh來區分單元,但是作業系統在往物理記憶體搬磚堆砌時,會給每塊磚不同的段起始地址,和偏移地址加在一起才是物理地址。這樣就不會發生重疊了。
當然這裡也有編譯器的功勞。編譯器除了造磚,還會生成一個規格標籤,用於通知作業系統這磚有多大多厚,讓作業系統能好好堆磚不浪費空間。不同作業系統的這種規格標籤格式不一樣,因此windows程式是不能直接跑在linux下的。
後來的處理器出現了mmu,記憶體管理單元,程式的地址空間和物理地址空間的換算就更復雜了。但是保證不同程式各自空間不發生覆蓋還是基本要求。
一個程式能覆蓋別的程式空間,大概是病毒惡意程式碼才做的事情。cpu的安全特性越來越強,這種情況很少見了吧。
-
4 # 移動海淘
每個進城都會由作業系統分配獨立的記憶體空間,所以不會覆蓋(緩衝區溢位和shellcode不算),不過也有病毒和外掛這些黑科技訪問其他進城的記憶體
-
5 # liu5241726
這個得分情況,在現代作業系統下,透過mmu會把程式的邏輯地址和記憶體物理地址做個對映,c程式編譯的時候,你會看到程式的邏輯地址一樣,但是cpu定址的時候會透過mmu和頁表把這個邏輯地址對映到真實的物理地址,作業系統做了地址隔離了。在沒有作業系統微控制器上,只有簡單的這個bootloader的話,c語言的編譯情況需要考慮地址了,因為這時候編譯出來的邏輯地址從某種程度上來說就是物理地址
-
6 # flappyer
32位系統下,Linux系統中每個程序都有獨立的3G虛擬使用者地址空間,每個虛地址空間單元為頁,透過MMU,頁表對映到物理頁幀and so on
-
7 # 跟我玩機械
一個是房子,一個是房子裡邊住的人,人可以換,房子的編號也可以改,甚至這一個房子裡可以註冊好幾家公司,只要訪子足夠大,隨便誰進來訪問任何一家公司都是可以的,我這樣說不知道對你有沒有幫助。
-
8 # fool_agui
最基本是堆疊技術,或現場保護程式(後臺執行),這些基本不需要由程式設計師來考慮。如果你需要具體瞭解這些地址位置,你需要掌握反彙編技術,透過對程式程式碼的分析來了解資料存放位置。有些程式碼是固化在Rom裡,不一定能讀出來,需要靠邏輯分析儀來解讀,很費時
載入到記憶體中不就會把另一個程式的指令覆蓋了嗎補充:是經過objdump以後,每條指令前面都有的那個地址,一般是0x400000左右,然後我還發現一些常數一般在0x600000左右,然後rsp棧頂指標一般是0x7fffffffff……
回覆列表
這涉及到作業系統知識,而且這個似乎沒寫在教科書上。
C編譯後的指令都寫在可執行檔案之中。所有指令地址都是從檔案某個偏移開始的。
當作業系統載入可執行程式並分配程序時,會為每個程序分配自己的獨有記憶體空間。
雖然兩個程序的某個記憶體地址數值相同,但他們物理記憶體地址絕不相同,程序的獨立記憶體空間只是對物理記憶體的一種對映關係而已。
再回到可執行指令載入話題。程式一般都有很多跳轉指令,它需要一個絕對記憶體地址,這個就要求作業系統在載入程序時,分配一個程序基礎地址,然後在所有跳轉指令,以及某些全域性變數地址中根據基礎地址調整記憶體地址。
不只是程序載入,其實動態庫載入都會涉及跳轉指令地址調整問題。
當然,早期系統,例如dos系統,沒有這套機制,它的程式記憶體地址都可以看作物理地址。但就現代作業系統來說,都是有這套機制的。