當前位置: 妍妍網 > 碼農

圖解:關於CPU技術12個知識點

2024-03-18碼農

點選上方 Linux開源社群 」,選擇「 設為星標

優質文章,及時送達

一、CPU是什麽?

CPU與電腦的關系就相當於大腦和人的關系,它是一種小型的電腦芯片,通常嵌入在電腦的主機板上。

CPU的構建是透過在單個電腦芯片上放置數十億個微型晶體管來實作。

這些晶體管使它能夠執行執行儲存在系統記憶體中的程式所需的計算,所以,也可以說CPU決定了你電腦的計算能力。

二、CPU實際做什麽?

CPU的工作核心是從程式或應用程式中獲取指令並且執行計算。

這個過程一共有三個關鍵階段:提取,解碼和執行。

CPU先從系統的RAM中提取指令,隨後解碼該指令的實際內容,最後再由CPU的相關部份執行該指令。

三、CPU的內部結構

剛才提到了很多CPU的重要性,那麽CPU的內部結構是什麽呢?又是由什麽組成的呢?

下圖展示了一般程式的執行流程(以C語言為例),一般來說,了解程式的執行流程是掌握程式執行機制的基礎和前提。

在這個流程中,CPU負責解釋和執行最終轉換成機器語言的內容,CPU主要由兩部份構成:控制單元和算數邏輯單元(ALU)。

  • 控制單元:從記憶體中提取指令並解碼執行;

  • 算數邏輯單元(ALU):處理算數和邏輯運算。

  • CPU和記憶體都是由許多晶體管組成的電子部件,可以把它比作電腦的心臟和大腦。

    它能夠接收數據輸入、執行指令並且處理相關資訊,它與輸入/輸出(I/O)裝置進行通訊,這些裝置向 CPU 發送數據和從 CPU 接收數據。

    從功能上來看,CPU的內容是由寄存器、控制器、運算器和時鐘四部份組成的,各個部份之間通電訊號來連通。

    接下來簡單介紹一下記憶體,為什麽說到CPU需要講一下記憶體呢?

    因為記憶體是與CPU進行溝通的橋梁,電腦中所有程式的執行都在記憶體中得到執行的。

    記憶體一般又被稱為主記憶體,它的作用是存放CPU中的運算數據,以及與硬碟等外部儲存裝置交換的數據。

    CPU會在電腦運轉時,把需要運算的數據調到主記憶體中進行運算。

    在運算完成之後,CPU將結果傳送出來,主記憶體的執行也決定了電腦的穩定執行。

    主記憶體一般透過控制芯片與CPU相連,由可讀寫的元素構成,每個字節都有一個地址編號。

    CPU透過地址從主記憶體中讀取數據和指令,也可以根據地址寫入數據,註意一點:當電腦關機時,記憶體中的指令和數據也會被清除。

    四、CPU是寄存器的集合體

    在CPU的四個結構中,寄存器的重要性遠遠高於其余三個,為什麽這麽說?因為程式通常是把寄存器作為物件來進行描述的。

    而說到寄存器,就不得不說到組合語言,說到組合語言,就不得不說到高級語言,說起高級語言也就不得不提及語言的概念。

    五、電腦語言

    人和人之間最古老和直接的溝通媒介是語言,但是和電腦溝通,就必須按照電腦指令來交換,其中就涉及到語言的問題。

    最早,為了解決電腦和人類的交流的問題,出現了組合語言。

    但是組合語言晦澀難懂,所以又出現了像是C、C++、Java的這種高級語言,因此電腦語言一般分為低階語言和高級語言。

    使用高級語言編寫的程式,經過編譯轉換成機器語言後才能執行,而組合語言經過組譯器才能轉換為機器語言。

    六、組合語言

    我們先來看一段采用組合語言表示的程式碼清單:

    這是采用組合語言編寫程式的一部份,組合語言采用助憶碼來編寫程式,每個原本是電訊號的機器語言指令會有一個與其對應的助憶碼。

    比如,mov,add分別是數據的儲存(move)和相加(addition)的簡寫。

    組合語言和機器語言一一對應,這點和高級語言不同,我們通常把組合語言編寫的程式轉換為機器語言的這個過程,稱之為組譯。

    與之相反,將機器語言轉化為組合語言的過程稱之為反組譯。

    組合語言可以幫助你理解電腦做了什麽工作,機器語言級別的程式透過寄存器來處理,上面程式碼中的eax,ebp都是表示的寄存器,它們是CPU內部寄存器的名稱。

    因此,可以說 CPU 是一系列寄存器的集合體。

    一般,在記憶體中的儲存透過地址編號來表示,寄存器的種類是透過名字來區分。

    那些不同型別的CPU,其內部寄存器的種類、數量以及寄存器儲存的數值範圍也都是不同的。

    不過,根據功能的不同,我們可以將寄存器劃分為下面幾類:

    其中,程式計數器、標誌寄存器、累加寄存器、指令寄存器和棧寄存器只有一個,其他寄存器一般有好幾個。

    七、程式計數器

    程式計數器是用來儲存下一條指令所在單元的地址。

    程式在執行時,PC的初值作為程式第一條指令的地址,在順序執行程式時,控制器先按照程式計數器所指出的指令地址,從記憶體中取出一條指令,隨後分析和執行該指令,並同時將PC的值加1指向下一條要執行的指令。

    我們可以透過一個事例來仔細看一下程式計數器的執行過程:

    這是一段進行相加的操作,程式啟動,在經過編譯解析後,會經由作業系統把硬碟中的程式復制到記憶體中。

    以上範例程式,就是將123和456執行相加的操作,隨後將結果輸出到顯視器上,因為使用機器語言很難描述,所以這些都是經過轉譯後的結果。

    事實上,每個指令和數據都有可能分布在不同的地址上,但是為了更好的說明,就把組成一條指令的記憶體和數據放在了一個記憶體地址上。

    地址0100是程式執行的起始位置,Windows等作業系統把程式從硬碟復制到記憶體以後,就會將程式計數器作為設定為起始位置0100,然後再執行程式,每次執行一條指令後,程式計數器的數值就會增加1,或者是直接指向下一條指令的地址。

    隨後,CPU會根據程式計數器的數值,從記憶體中讀取命令並且執行,換言之,程式計數器控制著程式的流程。

    八、條件分支和迴圈機制

    小夥伴們都學過高級語言,高級語言匯總的條件控制流程主要分為順序執行、條件分支、迴圈判斷三種。

  • 順序執行是按照地址的內容順序的執行命令。

  • 條件分支是根據條件執行任意地址的指令。

  • 迴圈是重復執行同一地址的指令。

  • 一般情況下,順序執行的情況較簡單,每次執行一條指令程式計數器的值就是+1。

    條件和迴圈分支會使得程式計數器的值指向任意的地址,這樣一來,程式就可以返回到上一個地址來重復執行同一個指令,或者跳轉到其它任意指令。

    下面,我們就以條件分支舉例來說明程式的執行過程:

    程式的開始過程和順序流程是一樣的,程式的順序流程和開始過程相同。

    CPU從0100處就開始執行命令,在0100和0101中都是順序執行,PC的值順序+1,執行到0102地址的指令時,判斷0106寄存器的數值大於0,跳轉到0104地址的指令,再將數值輸到顯視器中,隨後結束程式,0103的指令就被跳過了。

    這和我們程式中的if()判斷相同,在不滿足條件的情況下,指令一般會直接跳過。

    因此,PC的執行過程沒有直接+1,而是下一條指令的地址。微信搜尋公眾號:架構師指南,回復:架構師 領取資料 。

    九、標誌寄存器

    條件和迴圈分支會使用到 jump(跳轉指令),會根據當前的指令來判斷是否跳轉,上面我們提到了標誌寄存器,無論當前累加寄存器的運算結果是正數、負數還是零,標誌寄存器都會將其保存。

    CPU在進行運算時,標誌寄存器的數值會根據當前運算的結果自動設定,運算結果的正、負和零三種狀態由標誌寄存器的三個位表示。

    標誌寄存器的第一個字節位、第二個字節位、第三個字節位各自的結果都為1時,分別代表著正數、零和負數。

    CPU的執行機制比較有意思,假設累加寄存器中儲存的XXX和通用寄存器中儲存的YYY做比較,執行比較的背後,CPU的運算機制就會做減法運算。

    而無論減法運算的結果是正數、零還是負數,都會保存到標誌寄存器中。

    結果為正表示 XXX 比 YYY 大,結果為零表示 XXX 和 YYY 相等,結果為負表示 XXX 比 YYY 小,程式比較的指令,實際上是在 CPU 內部做減法運算。

    十、函式呼叫機制

    函式的呼叫和條件分支,迴圈機制有所不同,單純的跳轉指令無法實作函式的呼叫。

    函式的呼叫需要在函式內部處理後,處理流程在返回到函式呼叫點(函式呼叫指令的下一個地址)。

    函式的呼叫處理是透過把程式計數器的值設定成函式的儲存地址來實作的。

    十一、透過地址和索引實作陣列

    接下來是基址寄存器和變址寄存器,透過這兩個寄存器,可以對主記憶體上的特定區域進行劃分,以此實作類似陣列的操作。

    首先,可以用十六進制數將電腦記憶體上的 00000000 - FFFFFFFF 的地址劃分出來。

    這樣,凡是該範圍的記憶體地址,只要有一個 32 位的寄存器,就可以檢視全部地址。

    但是,要是想像陣列那樣,分割特定的記憶體區域以達到連續檢視的目的的話,使用兩個寄存器會更方便一些,比如,我們用兩個寄存器來表示記憶體的值。

    這種表示方式很像陣列的構造,陣列是指同樣長度的數據,在記憶體中進行連續排列的數據構造。

    用陣列名表示陣列全部的值,透過索引來區分陣列的各個數據元素,例如: a[0] - a[4],[]內的 0 - 4 就是陣列的下標。

    十二、CPU指令執行過程

    那說了這麽多,CPU到底是怎麽一條條的執行指令的呢?幾乎全部的馮·紐曼型電腦的CPU,工作都可以分為5個階段:取指令、指令譯碼、執行指令、訪存取數、結果寫回。

    取指令階段就是將記憶體中的指令讀取到CPU中寄存器的過程,程式寄存器用於儲存下一條指令所在的地址;

    在取指令完成後,立馬進入指令譯碼階段,在指令譯碼階段,指令編碼器按照預先的指令格式,對取回的指令進行拆分和解釋,辨識區分出不同的指令類別和各種獲取運算元的方法;

    執行指令階段的任務是完成指令所規定的各種操作,具體實作指令的功能;

    存取取數階段的任務是:根據指令地址碼,得到運算元在主記憶體中的地址,並從主記憶體中讀取該運算元用於運算;

    結果寫回階段作為最後一個階段,把執行指令階段的執行結果數據「寫回」到某種儲存形式:結果數據經常被寫到CPU的內部寄存器中,以便被後續的指令快速地存取。

    出品 | 安東工作室

    來源|知乎等網路

    -End-

    讀到這裏說明你喜歡本公眾號的文章,歡迎 置頂(標星)本公眾號 Linux技術迷,這樣就可以第一時間獲取推播了~

    本公眾號,後台回復:Linux,領取2T學習資料 !

    1. 

    2. 

    3.

    4.