1. 程式人生 > >3-淺談8086CPU的記憶體分段機制

3-淺談8086CPU的記憶體分段機制

1. 記憶體分段

在上一篇我們知道8086CPU在訪問記憶體使用了分段機制,即通過“(段地址×16)+偏移地址=實體地址”的方式來確定記憶體單元的實體地址,需要明白的是記憶體空間是一個連續的線性空間,對於記憶體本身來說並沒有劃分段,這其實是CPU為了方便定址而使用了記憶體分段機制。

簡單一句話理解就是記憶體本身並不分段,而是CPU為了方便定址對記憶體進行了分段(對於這種說法,可能會對初學者產生一種誤解,誤認為記憶體好像分成了一個一個段,每一個段都有一個段地址,但是我們需要明確這種說法只是針對CPU的,而不是記憶體本身)。CPU對記憶體分段的目的是為了方便管理,降低程式開發難度,為設計功能更可靠,規模更大的程式奠定基礎

。 

 

 

同一段記憶體,多種分段方案如下:

10000H到100FFH組成一個段,起始地址( 基礎地址,向左移4位) 為10000H,段地址為1000H, 偏移的大小為100H。當這段記憶體分成兩個段後,起始地址( 基礎地址 )為10000H和10080H,段地址為1000H和1008H, 大小均為80H。

 

我們知道當段地址向左移4位,實際上就是乘以16,換句話說一個段的起始地址也一定是16的倍數。

偏移地址為16位,16 位地址的定址能力為64K,所以一個段的長度最大為64K。

 

現在有一個實體地址為21F60H,段地址為2000H,把段地址向左移4位後就是20000H,再用實體地址減去段地址,那麼就很容易推出偏移地址為1F60H。

 

在8086PC機中儲存單元地址是怎樣表示的呢?如果資料在21F60H記憶體單元中,段地址是2000H,地址表示如下:

  1. 資料存在記憶體2000:1F60單元中
  2. 資料存在記憶體的2000H段中的1F60H單元中

另外,段地址和資料都是重要的,因此處理器至少需要提供兩個段暫存器,分別是程式碼段暫存器(Code Segment,CS)和資料段暫存器(Data Segment,DS)。對CS內容的改變將導致處理器從新的程式碼段開始執行。同樣的,在開始訪問記憶體中的資料之前,也必須讓DS暫存器指向資料段。

通常情況下,段地址的選擇取決於記憶體中哪些區域是空閒的,例如從實體地址00000H開始,到82215H之間的記憶體都被其他程式佔用了,那麼可以從82215H後面的空閒的記憶體區域開始載入程式。

 

2. 程式碼段和資料段

程式的本質上是一個機器指令的集合,這一堆指令會放到記憶體中的某個位置。處理器是自動化器件,在給出了起始地之後,就從這個地址開始自動的取出每一條指令並執行,這意味著程式的所有指令都必須集中在一起,形成一個段,而這個段就叫程式碼段。

CPU執行指令的時候,總是會需要使用一些資料進行運算,這些資料也會集中放在記憶體的某個位置,形成一個段,叫資料段。前面我們也說過,記憶體是不存在分段的,所以無論是程式碼段,還是資料段,這些都是我們抽象出來的,實際上並沒有改變記憶體的物理性質。

對於CPU來說,它根本不理解什麼程式碼段和資料段,CPU只是受到程式設計師的控制,從哪裡獲取指令,從哪裡獲取資料,做什麼運算處理等。如果下一次執行程式時,程式碼段和資料段在記憶體的位置發生了變化,那麼只要把它們的段地址傳到DS和CS暫存器中,那麼CPU就能夠從DS和CS暫存器知道資料段的段地址和程式碼段的段地址,從而正確的執行程式。