——>如何讓內存用起來?
我們知道CPU的工作過程是取指執行,取指令就是在內存中的相應位置取指令,因此CPU和內存是同步工作的。如下圖所示
程序原本存放在磁盤中,要使用時先加載進內存,那麼程序就要在內存中找塊地址放進去
原本程序在磁盤中存在0位置,main函數存在40位置,直觀的做法就是,把程序地址原封不動讀入內存的相應位置,那麼問題來了,下次載入其他程序時,也有可能使用0和40位置,況且內存的0位置存的是操作系統的初始位置,這樣顯然行不通,那麼行的通的辦法時,在內存中找一塊空閒的地址放入程序,起始位置作爲基地址,程序中的物理地址爲基地址+磁盤中的邏輯地址
將程序在磁盤中的地址修改爲內存中地址的操作叫作重定位
那麼應該在什麼時候完成重定位呢
- 編譯時:但編譯時很難知道內存中哪些位置是空閒的,重定位的程序只能存放在內存固定位置,適用於單片機這種靜態的嵌入式系統
- 載入時:載入時重定位的程序一旦載入內存就不能動了
常用的計算機程序載入後還需要移動的
比如某個進程長時間阻塞,就應該把它換出,釋放出內存讓給其他進程,這樣才能充分利用內存,並且內存的大小是有限的,如果運行的進程比較多,就必須要支持換入換出操作,如下圖所示
由於進程存在換入換出操作,那麼進程(運行的程序)在內存的存放地址就會發生改變,因此程序合理的重定位時機應該在運行時重定位
每執行一條指令都要從邏輯地址算出物理地址:地址翻譯
執行指令時第一步是從PCB中取出基地址,物理地址=基地址+邏輯地址
那麼執行指令的過程如下圖所示
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>分割線>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
引入分段:程序載入內存時是將整個程序載入一段連續的內存嗎?
程序員眼中的程序:由若干分段組成,每個段有各自的特點、用途->代碼段只讀,代碼段/數據段不會動態增長,但是堆棧段空間會動態變化
將靜態的短和動態的段放在一起容易引起互相干擾,並且若整個程序連續存儲,那麼堆棧段變化時,整段程序都要移動(類似數組的插入刪除),如果分段存儲,堆棧段動態變化時只會引起堆棧段的內存變化。
所以,程序應該在內存中分段存儲,那麼每次計算指令的物理地址時就要根據不同的段基址計算,而不是整個程序只有一個基址,如下圖所示
程序中每段的基址存在進程表中,進程表又保存在PCB中,因此進程切換時,進程表也會切換,進程表(LDT)類
似操作系統啓動時的GDT(全局描述表),LDT又叫局部描述表它們的關係如下圖所示