CPU的工作原理


一、CPU的組成部分

1.1、計算機五大部件

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 說起計算機五大件,筆者想起在大學的時候,老師問我們計算機硬件的五大部件有什么,然后聽到有同學回答說鼠標,鍵盤,顯示器什么的,把老師逗樂了,說我們計算機系的還這么小白。其實也正常,誰不是從小白慢慢成為技術大牛呢...

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 言歸正傳,計算機硬件的五大件分為:輸入設備,輸出設備,運算器,控制器,儲存器。輸入,輸出設備主要就是鼠標,鍵盤,顯示器還有打印機等等。儲存器主要分為內存和磁盤,內存是儲存程序運行時的指令和數據。本章主要圍繞着控制器和運算器來講,因為它們都是CPU的組成部分。

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 按實際硬件分,CPU內部是由寄存器,控制器,運算器,時鍾四個部分組成:

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 寄存器:暫存指令和數據,可以看作是一級內存;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 控制器:負責把內存上的指令,數據讀入寄存器;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 運算器:負責運算從內存讀入寄存器的數據;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 時鍾:負責發出CPU開始計時的時鍾信號;

​​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 一個CPU可以有多個寄存器。

1.2、寄存器的分類和功能

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ x86系列32位CPU的寄存器主要分為累加寄存器,標志寄存器,程序計數器,基址寄存器,棧指針寄存器,通用寄存器等;累加寄存器,標志寄存器,程序計數器都只有一個,其他寄存器一般有多個。32位CPU是指寄存器可以存儲4個字節。

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 累加寄存器(eax)(這個是運算器):存儲執行運算的數據和運算后的數據;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 標志寄存器:存儲運算處理后的CPU的狀態;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 程序計數器(epc)(這個是控制器)的作用是存儲下一條指令所在的內存地址;比如程序需要實現123和456相加,並輸出結果到顯示器。程序開始運行時,程序計數器儲存程序初始的內存地址比如是0100,CPU每執行一個指令,程序計數器存儲的內存地址就會加1(程序流程分為順序執行,跳轉,循環),這里只拿順序執行,如下圖:

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 基址寄存器(ebp):存儲數據存儲領域基點的內存地址;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 棧指針寄存器(esp):存儲棧中最高位數據的內存地址;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 通用寄存器:存儲任意數據;

二、程序在CPU的執行過程

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 程序是指令和數據的集合,不管是C、PHP、GO等其他語言寫的程序,到最后都是編譯成機器語言,就是一系列的指令,程序運行時CPU則依次執行每一行的指令,根據運算結果來控制整個計算機的輸入還是輸出。程序運行時,是先從把程序在磁盤上復制到內存,然后根據程序計數器指定的內存地址,把程序的指令從內存上讀到指定寄存器進行運算。

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ CPU能識別的機器語言,像這種00111110二進制數值,在我們人類看是很難理解的,為了人類能夠方便理解機器語言,就發明了助記符,每個助記符都一一對應機器語言,這種助記符對應機器語言的方式就是匯編,匯編語言是直接反應機器語言的程序運行情況。比如助記符LD A , 207,對應的機器碼是00111110 11001111。LD A , 207的意思是把數值207寫入到A寄存器。LD 是操作碼;A,207是操作數。

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 下面用高級語言(比如C、PHP、GO)轉換成匯編(低級語言),通過匯編來理解程序的指令在CPU上是怎么運作的:

下面是簡單的C程序:

int add_a_and_b(int a, int b) {
   return a + b;
}

int main() {
   return add_a_and_b(2, 3);
}

通過匯編器轉換成匯編(省略了匯編器生成的段定義和偽指令,這里只是為了理解程序執行過程):

_add_a_and_b:
         push  ebp
	 mov   ebp,esp
	 mov   eax,dword ptr [ebp+8]  ;[ebp+8]指定棧中儲存的數值2,傳人eax寄存器
	 add   eax,dword ptr [ebp+12]	;[ebp+12]指定棧中儲存的數值3,再跟eax寄存器存儲的值相加,結果存入eax
	 pop   ebp
         ret
	
_main:
	 push  ebp
	 mov   ebp,esp
         push  3
         push  2
         call  _add_a_and_b 
         add   esp,8
         pop   ebp
         ret

解釋上面匯編代碼:

dword ptr 表示從指定內存地址讀出4個字節數據;

_main,_add_a_and_b是函數標簽;

操作碼​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 操作數​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 說明

push​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ebp​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 把ebp寄存器里存儲的內存地址存入棧中(32位CPU,占用4個字節)

mov​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ebp,esp​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​​把esp寄存器里存儲的內存地址傳到ebp寄存器

push​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 3​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​把3放入棧中(占用4個字節)

push​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 2​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​把2放入棧中(占用4個字節)

call​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ _add_a_and_b ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​調用函數

add​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ esp,8​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ esp寄存器存儲的內存地址值加8(棧存儲數據是從高地址到低地址開始存儲,上面加入了3和2,故加8來清理棧中數據)

pop ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ebp ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​讀出棧中的數值存入ebp寄存器

ret​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​結束main函數,返回調用源

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 每次調用函數時,都要執行push ebp mov ebp,esp,這兩個指令,是因為函數內可能要用到ebp寄存器,所以先把ebp寄存器原來的數值存入棧中,再把當前存儲在esp上的棧頂地址傳給ebp;函數調用結束后,執行add esp,8 pop ebp來進行占空間清理,再把ebp原來的數值傳入ebp寄存器;

​​ ​ ​ ​ ​ ​ ​ ​ ​ ​ 上面的函數調用,函數返回時,程序計數器里存儲的地址又回到函數調用的下一個指令,實現的原因是:在進行函數調用前先把函數調用的下一個指令存儲到棧中,調用完再把棧上的返回目的地址的內存地址(目的地址的內存是指函數調用完,回到下一個指令的地址。)傳入程序計數器存儲。上面的程序內存里棧空間是這樣的:

總結:計算機的運行機制其實很簡單,就是照着程序員寫好的程序(源文件),翻譯成CPU能理解的二進制指令(本地代碼)從上往下逐步的執行。如今的編程從面向過程,到面向對象,這個發展無非是越來越接近人類,從難於理解的機器碼,到用英文對應機器碼的匯編,再發展到面向對象編程,都是為了增加代碼的可讀性,可維護性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM