讓梁大俠頭疼的CPU段式結構的由來

2021-03-31 13:09:56 字數 2184 閱讀 6522

梁在其《程式設計高手箴言》一書第二章說:

8086

最頭疼的問題在於段式結構,

1mb的記憶體被它的段偏移所限制。至今我也不明白

intel

當初為什何要設計成這麼複雜的記憶體機制,也許是為了與

8080

相容的需要。這套笨拙的體系一直延續到

ia64

為止。以下文字參考

linux

核心源**情景分析

一書。當我們說乙個

cpu是

」16位」或

」32」

位時,指的是處理器中

」算術邏輯單元」[

alu]的寬度。系統匯流排中的資料線部分,稱為資料匯流排,它通常與

alu有相同的寬度。另外,還有一條位址匯流排來訪問記憶體,它的寬度應該與資料匯流排一致,這是因為從程式設計的角度來說,乙個位址是乙個指標,最好與

cpu所處理的乙個整數的寬度一致,但實際情況是不可能這樣的。8位

cpu如果讓位址匯流排也是

8位,那只能定址

256個不同的位址單元,太小了。所以8位的

cpu的位址匯流排通常是

16位的,但這樣,在

8位的指令系統中常存在著一些

16位的操作。後來

cpu發展到了

16位,本來位址匯流排和資料匯流排的寬度應該可以一致了,但當時人們又覺得

16位的位址匯流排可以定址的空間還是太小啊,還要加大。那加到多大?

intel

結合當時人們所能看到的微型計算機的應用前景以及儲存器晶元的**,決定用

1mb。由此可見,

cpu的位址匯流排不是你覺得多少位好就採用多少位的寬度了,它要對當時儲存器的價位進行衡量才可以確定要多少位的位址匯流排,假如當時人們不是普遍覺得

1mb記憶體足夠用的話,那麼

cpu發展到我們今天就有可能不是現在這樣了,可能

32位的位址匯流排就在

8086

中出現了。就這樣,

8086

決定要用

1mb的記憶體時,那麼位址匯流排就必須是

20位的寬度,但

cpu的

alu的寬度只有

16位,也就是說在記憶體定址時參與計算的位址指標也只能是

16位的。該如何解決這個問題,這應該是當時很困擾

intel

的設計人員的問題,如果像

8位計算機所做的那樣,在

cpu的指令集中新增一些

20位的指令來進行記憶體定址,這樣會導致

cpu內部結構的不均勻性

(想一想就知道了,

cpu內部的電路系統又要處理

16位的指令,又要處理

20位的指令,麻煩不麻煩?)。

intel

設計人員後來選擇了分段機制,這在當時看來應該是很巧妙的方法了。當時

pdp-ii

小型機也是

16位的,但它可以通過記憶體管理機制將

16位的位址對映到

24位的位址空間,

intel

應該是借鑑了它的思路。

intel

在8086cpu

中設定了四個

」段暫存器

」,每個段暫存器都是

16位的,對應於位址匯流排的高

16位。每條訪問記憶體的指令中的內部位址也都是

16位的,但是在將位址傳到位址匯流排上之前,要使用

cpu內部的加法器對內部位址和某個段暫存器中的位址相加,形成乙個

20位的位址。由於段暫存器中的內容對應於

20位位址匯流排中的高

16位,所以在相加時是拿內部位址的高

12位與段暫存器中的

16位相加,而內部位址中的低四位保持不變。這個方法與作業系統理論中的

」段式記憶體管理

」相似,但並不完全一樣,主要是沒有位址空間的保護機制,對每乙個由段暫存器的內容確定的

」基位址

」,乙個程序總是能夠訪問從此開始的

64k位元組的連續空間,而無法加以限制。同時,可以用來改變段暫存器內容的指令也不是什麼

」特權指令

」,也就是說通過改變段暫存器的內容,乙個程序可以隨心所欲地訪問記憶體中的任何乙個單元,而絲毫不受到限制,能對乙個程序的記憶體訪問加以限制,也就談不上對其他程序以及系統本身的保護。與此相應,乙個

cpu如果缺乏對記憶體訪問的限制,就談不上什麼記憶體管理,也就談不上是現代意義上的**處理器。由此,而生出

」保護模式

」的概念。

CPU段式結構的由來

梁說 8086 最頭疼的問題在於段式結構,1mb的記憶體被它的段偏移所限制。至今我也不明白 intel 當初為什何要設計成這麼複雜的記憶體機制,也許是為了與 8080 相容的需要。這套笨拙的體系一直延續到 ia64 為止。以下文字參考 linux 核心源 情景分析 一書。當我們說乙個 cpu是 16...

讓人頭疼的遞迴演算法

遞迴,一般指函式的定義中使用函式自身的方法。也就是說,遞迴演算法是一種直接或者間接呼叫自身函式方法的演算法。實質上是把問題分解成規模縮小的同類問題的子問題,然後遞迴呼叫方法來表示問題的解。基本原理 1.每一級的函式呼叫都有自己的變數。2.每一次函式呼叫都會有一次返回。3.遞迴函式中位於遞迴呼叫前的語...

讓人頭疼的稀疏陣列

當乙個陣列中大部分元素為0,或者為同乙個值的陣列時,可以使用稀疏陣列來儲存該陣列.package main import fmt type valnode struct func main fmt.println 3.轉成稀疏陣列。想 演算法 思路 1 遍歷 chessmap,如果我們發現有乙個元素...