CPU的內部結構
?CPU是中央處理器Central Processing Unit的縮寫,相當于計算機的大腦,它的內部由數百萬至數億個 「晶體管」 構成。
?
在 「程序運行流程」 中,CPU
所負責的就是 「解釋和運行」 最終轉換成 「機器語言」 的程序內容。
程序運行流程
CPU
和內存是由許多晶體管組成的 「電子部件」 ,通常成為集成電路Integrated Circuit。
?從功能方面來看,
CPU
的內部是由 「寄存器」 、 「控制器」 、 「運算器」 、 「時鐘」 等四個部分組成,各個部分之間由 「電流信號」 相互連通。?
CPU的四個組成部分
- 「寄存器」
- 用來 「緩存」 指令、數據等處理對象,可以將其看作是**「內存的一種」**
- 根據種類的不同,一個
CPU
內部戶有20~100
個寄存器
- 「控制器」
- 負責把 「內存」 上的指令、數據等讀入**「寄存器」**
- 并根據指令的執行結果來 「控制」 整個計算機
- 「運算器」
- 負責運算**「從內存讀入寄存器的數據」**
- 「時鐘」
- 負責發出
CPU
開始計時的**「時鐘信號」**
- 負責發出
內存
?通常所說的 「內存」 指的是計算機的主要存儲器Main Memory,簡稱 「主存」 。
?
主存
通過 「控制芯片」 等與CPU
相連,主要負責 「存儲指令和數據」 。主存由 「可讀寫」 的元素構成,每個字節(1字節=8位
)都帶有一個 「地址編號」 。CPU
可以通過該地址 「讀取」 主存中的指令和數據,當然也可以 「寫入」 數據。
程序運行機制
程序啟動后,根據 「時鐘信號」 , 「控制器」 會從 「內存」 中讀取指令和數據。通過對這些指令加以解釋和運行, 「運算器」 就會對數據進行運算, 「控制器」 根據該運算結果來控制計算機。
CPU是寄存器的集合體
CPU
的四個構成部分中,我們只需要了解寄存器即可。這是因為, 「程序是把寄存器作為對象來描述的」 。
假設,我們存在如下用匯編語言編寫的代碼。
? 「匯編語言」 采用助記符Memonic來編寫程序,每一個原本是 「電氣信號」 的 「機器語言指令」 都有有一個與其 「相對應的助記符」 。
助記符通常為指令功能的英語單詞的縮寫。
?
匯編代碼
例如,mov
和add
分別是數據的存儲和相加的簡寫。
?「匯編語言和機器語言基本上是一一對應的」
?
- 通常我們將 「匯編語言」 編寫的程序轉化成 「機器語言」 的過程稱為**「匯編」**
- 反之, 「機器語言」 程序轉化成 「匯編語言」 的程序的過程稱為**「反匯編」**
從上述的 「匯編代碼」 中,我們可以看出, 「機器語言級別的程序是通過寄存器來處理的」 ,也就是說, 「CPU是寄存器的集合體」 。eax
和ebp
表示的都是寄存器。并且,內存的存儲場所 「通過地址編號來區分」 ,而寄存器的種類 「通過名字來區分」 。
CPU
處理程序的大致過程如下:
?使用 「高級語言」 編寫的程序會在 「編譯」 后轉化成 「機器語言」 ,然后再通過
CPU
內部的寄存器來處理。?
寄存器的種類
?不同類型的
CPU
,其內部寄存器的數量、種類以及寄存器存儲的數值范圍都是不同的。?
不過,根據功能的不同,我們可以將寄存器大致分為 「8類」 。
寄存器的主要種類和功能
可以看出,寄存器中存儲的內容既 「可以是指令也可以是數據」 。其中,數據分為 「用于運算的數據」 和**「表示內存地址的數據」**
CPU是寄存器的集合體
決定程序流程的程序計數器
只有1行的有用程序是很少見的,機器語言的程序也是如此。接下來,我們看一下程序是如何按照流程運行的。
下圖是程序啟動后的內存內容的模型。
?用戶發出啟動程序的指示后, 「操作系統」 會把 「硬盤」 中保存的程序 「復制」 到 「內存」 中。
?
實例中的程序實現的是將123
和456
兩個數值相加,并將結果輸出到顯示器上。
前面我們已經介紹過,存儲指令和數據的內存,是通過地址來劃分的。由于使用機器語言難以清晰地表明各地址存儲的內容,因此我們對各地址的存儲內容添加注釋。實際上, 「一個命令和數據通常被存儲在多個地址上」 ,但是為了便于說明,上面的圖例中,把指令、數據分配到一個地址中。
大致流程如下:
- 地址
0100
是程序運行的開始位置。 - 操作系統把程序從 「硬盤」 復制到 「內存」 后,會將 「程序計數器」 (
CPU
寄存器的一種)設定為0100
,然后程序便開始運行。 - 「
CPU
每執行一個指令,程序計數器的值就會自動加1」 - 然后,
CPU
的 「控制器」 就會參照程序計數器的數值,從內存中讀取命令并執行。
?程序計數器決定著程序的流程
?
條件分支和循環機制
程序的流程分為 「順序執行」 、 「條件分支」 和 「循環」 三種。
- 「順序執行」 是指按照地址內容的順序執行指令
- 「條件分支」 是指根據條件執行任意地址的指令
- 「循環」 是指重復執行同一地址的指令
「順序執行」 的情況比較簡單,每執行一個指令 「程序計數器」 的值就 「自動加1」 .但若程序中存在 「條件分支」 和 「循環」 ,機器語言的指令就可以將 「程序計數器」 的值設定為 「任意地址」 (不是加1)。這樣一來,程序便可以返回到上一個地址來重復執行同一個指令,或者跳轉到任意地址。
條件分支運行流程
上圖表示把內存中存儲的數值(示例中是123)的絕對值輸出到顯示器的程序的內存狀態。
大致流程如下:
- 程序運行的開始位置是
0100
地址 - 隨著 「程序計數器」 數值的增加
- 當到達
0102
地址時,如果 「累加寄存器」 的值是 「正數」 ,則執行 「跳轉指令」 (jump
指令)跳轉到0104
地址 - 此時,由于 「累加寄存器」 的值是
123
,為 「正數」 ,因此0103
地址的指令被跳過,程序的流程 「直接」 跳轉到了0104
地址
? 「條件分支」 和 「循環」 中使用的 「跳轉指令」 ,會參照當前執行的 「運算結果」 來判斷是否跳轉。
?
前面我們提到過 「標志寄存器」 。無論當前 「累加寄存器」 的運算結果是負數、零還是正數, 「標志寄存器」 都會將其保存。
CPU
在進行運算時, 「標志寄存器」 的數值會根據運算結果 「自動設定」 。至于是否執行 「跳轉指令」 ,則由CPU
在參考 「標志寄存器」 的數值后進行判斷。運算結果的正、零、負 「三個狀態」 由 「標志寄存器」 的三個位表示。
32位CPU(寄存器的長度是32位)的標志寄存器的示例
「標志寄存器」 的第一個字節位、第二個字節位和第三個字節位的值為1時,表示的運算結果分別為正數、零和負數。
CPU比較機制
假設要比較 「累加寄存器」 中存儲的XXX
值和 「通用寄存器」 中存儲的YYY
值,執行比較的指令后,CPU
的運算裝置就會在內部進行XXX-YYY
的 「減法運行」 。
無論減法運算的結果是正數、零還是負數,都會被保存到 「標志寄存器」 中。
- 結果為 「正」 表示
XXX
比YYY
大 - 結果為 「零」 表示
XXX
和YYY
相等 - 結果為 「負」 表示
XXX
和YYY
小
?程序中的比較指令,就是在
CPU
內部做減法運算?
函數的調用機制
?函數調用處理也是通過把 「程序計數器」 的值設定成函數的存儲地址來實現的
?
和 「條件分支」 、 「循環」 的機制不同,因為單純的跳轉指令無法實現函數的調用。
?函數的調用需要在完成函數內部的處理后,處理流程再返回到函數調用點( 「函數調用指令的下一個地址」 )
?
上圖的示例為 變量a
和b
分別代入123
和456
后,將其賦值給參數來調用MyFunc
函數的C
語言程序。圖中的地址是將C
語言編譯成機器語言后運行時的地址。由于1行C
語言程序在編譯后通常會變成多行的機器語言,所以圖中的地址是 「離散」 的。
此外,通過 「跳轉指令」 把 「程序計數器」 的值設定為0260
也可以實現調用MyFunc
函數。函數的 「調用原點」 (0132
地址)和 「被調用函數」 (0260
地址)之間的數據傳遞,可以通過內存或寄存器來實現。
當函數處理進行到最后的0354
地址時,我們應該將 「程序計數器」 的值設定成函數調用后要執行的0154
地址。我們通過機器語言的call
指令和return
指令能實現該功能。
call 指令和return 指令
?函數調用使用的是
call
指令,而不是跳轉指令。?
在將函數的入口地址設定到 「程序計數器」 之前, 「call指令」 會把調用函數后要執行的指令地址存儲在名為 「?!?/strong> 的內存內。 「return 指令」 的功能是把保存在棧中的地址設定到 「程序計數器」 中。
通過地址和索引實現數組
?通過 「基址寄存器」 和 「變址寄存器」 可以對 「主內存」 上特定的內存區域進行劃分,從而實現類似于數組的操作
?
- 用 「十六進制數」 將計算機內存上
00000000~FFFFFFFF
的地址劃分出來- 凡是該范圍的內存區域,只要有一個32位的寄存器,即可查看全部的內存地址
- 如果想要像數組那樣分割特定的內存區域以達到連續查看的目的,使用兩個寄存器會更方便
?
CPU
會把 「基址寄存器」 + 「變址寄存器」 的值解釋為實際查看的內存地址。?
「變址寄存器」 的值相當于高級程序語言程序中數組的**「索引功能」**
-
cpu
+關注
關注
68文章
10876瀏覽量
212125 -
計算機
+關注
關注
19文章
7513瀏覽量
88173 -
晶體管
+關注
關注
77文章
9703瀏覽量
138446
發布評論請先 登錄
相關推薦
評論