虛擬記憶體與記憶體映射
虛擬位址與實體位址
把虛擬位址想成印在某位住戶私人通訊錄上的公寓號碼——「12 號公寓」——而實體位址則是大樓真正擁有的樓層與單位,例如「七樓 3 室」。住戶永遠只用自己私有的號碼說話;一位管理員默默地把每個號碼換成真實位置。虛擬位址(virtual address)是你程式所用的號碼;實體位址(physical address)則是 RAM 晶片上真正的地點。
一般 C 程式碰到的每個位址都是虛擬的:rsp 指向的堆疊位址、&x 給你的值、malloc() 回傳的指標。硬體在記憶體晶片真正被讀寫之前,會藉助作業系統填好的表,把每個虛擬位址轉譯成一個實體位址。這兩個號碼通常完全不同,甚至同一個實體位元組在不同程式裡可以有不同的虛擬位址(共享函式庫就是這樣被共用的)。你的程式永遠看不到實體號碼,正常情況下也查不出來。
為什麼要把兩者分開?因為所有威力都藏在這層間接(indirection)裡。作業系統可以把程式的資料搬到不同的實體地點、讓多個程式共用同一份實體副本、把某個分頁標成唯讀,甚至讓某個虛擬位址在第一次被碰之前都沒有實體歸宿——而程式全程毫無察覺,因為程式只認得自己那些穩定的虛擬號碼。
你的程式讀取虛擬位址 0x401000。分頁表說虛擬分頁 0x401 目前住在實體頁框 0x9c2,於是硬體真正讀的是實體位址 0x9c2000 加上同樣的頁內偏移量。下次你再跑這支程式時,虛擬的 0x401000 可能對映到完全不同的實體頁框。
虛擬號碼對程式來說是穩定的;實體號碼是作業系統的事。
你幾乎不會從使用者程式碼看到實體位址,也不該嘗試去看——印出來的指標(例如 0x7ffd...)是虛擬的。實體位址是核心與硬體的事;把虛擬指標當成硬體位置是觀念上的錯置。
又稱
另見