4

考慮以下CPU指令這需要存儲器地址16777386(十進制),並將其存儲在寄存器1:在編譯時何時分配內存地址?

Move &0x010000AA, R1

傳統節目被轉換到組件(機器代碼)。 (讓我們忽略更復雜的現代系統,如jitting)。

但是,如果此地址分配在編譯時靜態完成,那麼操作系統如何確保兩個進程不使用相同的內存? (例如,如果你同時運行兩次相同的編譯程序)。

問:

如何,以及何時,並計劃得到分配的內存地址?

虛擬內存:

我瞭解大部分(如果不是全部)現代系統使用存儲器管理單元在硬件上允許使用的虛擬內存。地址空間的前幾個八位字節用於引用哪個頁面。如果每個進程使用不同的頁面,這將允許內存保護。但是,如果這是如何執行內存保護的,那麼原始問題仍然存在,只是這次是如何分配頁碼的?

EDIT

CPU:

一種可能性是CPU可以通過執行一個進程ID由OS執行基於存儲器中的指令前分配處理存儲器保護。但是,這只是推測,並且需要CPU架構在硬件方面的支持,這是我不確定RISC ISA會設計的。

回答

1

虛擬內存每個進程都有獨立的地址空間,所以一個進程中的0x010000AA會引用與另一個進程中不同的值。

地址空間是由內核控制的page tables實現的,處理器用它來將虛擬頁面地址轉換爲物理地址。使用相同地址頁碼的兩個進程不是問題,因爲進程具有單獨的頁表,並且映射的物理內存可能不同。

通常可執行代碼和全局變量將被靜態映射,堆棧將被映射到隨機地址(某些漏洞更加困難),動態分配例程將使用系統調用來映射更多頁面。

+0

其我的理解是,頁面查找使用硬件以減少查找的時間成本(是內核接管頁面錯誤,但應該是例外情況)。 MMU跟蹤哪個進程正在運行?它如何知道一次將0x010000AA映射到物理地址X,但稍後將0x010000AA映射到物理地址Y? – James 2014-11-24 16:58:52

+0

@詹姆斯,處理器需要一個指向頁表的寄存器(例如,x86 http://en.wikipedia.org/wiki/Control_register#CR3中的CR3)。 – zch 2014-11-24 17:16:14

0

(忽略Unix分支)進程內存的初始狀態由可執行加載程序設置。鏈接器定義了初始內存狀態,加載器創建它。該狀態通常包括靜態數據,可執行代碼,可寫入數據和堆棧的內存。

在大多數系統中,進程可以通過添加頁面(也可能刪除它們)來修改地址空間。

[忽略系統地址]在虛擬(邏輯)內存系統中,每個進程都有一個從零開始的地址空間(通常第一頁未映射)。地址空間分爲多頁。操作系統將邏輯頁面映射(並重新映射)爲物理頁面。

地址0x010000AA在一個進程中是每個進程中不同的物理內存地址。