計算機指令
從軟體工程師的角度來看,CPU是執行計算機指令的邏輯機器。計算機指令可以看作是CPU能夠理解的語言,也稱為機器語言。
不同的CPU能理解的語言不同。例如,個人電腦使用Intel的CPU,蘋果手機使用ARM的CPU。這兩種CPU支援的語言不同。這些不同CPU支援的語言被稱為不同的指令集。
不同的CPU有不同的指令集,對應不同的組合語言和機器碼。為了簡化機器碼的理解,我們選擇了最簡單的MIPS指令集來說明機器碼的生成過程。MIPS是由MIPS技術公司在80年代中期設計的CPU指令集。不久前,MIPS公司將整個指令集和晶片架構完全開源。
MIPS指令是一個32位的整數,其中高6位是操作碼,表示具體的指令型別,剩下的26位有三種格式:R、I和J。
- R指令通常用於算術和邏輯操作,包括讀取和寫入暫存器的地址。對於邏輯位移操作,還需要位移操作的位移量。最後的功能碼錶示具體的指令。
- I指令通常用於資料傳輸、條件分支和運算時使用的非變數或常數。它沒有位移量和操作碼,也沒有第三個暫存器,而是將這三部分直接合併成一個地址值或常數。
- J指令是跳轉指令,高6位之外的26位是跳轉後的地址。
// test.c
int main()
{
int a = 1;
int b = 2;
a = a + b;
}
為了在Linux作業系統上執行這段程式碼,我們需要將整個程式編譯成組合語言的程式碼。然後使用匯編器將彙編程式碼翻譯成機器碼。這些機器碼由0和1組成的機器語言表示。每條機器碼都是一條計算機指令。這些16進位制數字就是CPU可以識別的計算機指令。
彙編程式碼實際上就是給程式設計師看的機器碼。由於難以理解8b 45 f8這樣的機器碼,人類更容易記住用英文表示的指令,如add、mov等。
從高階語言到彙編程式碼,再到機器碼,是將開發的程式轉變為CPU可以執行的計算機指令的過程。
CPU如何執行指令
CPU 內部處理過程
下圖展示了一般程式(以 C 語言為例,java語言類似)的執行流程。瞭解程式的執行流程是掌握程式執行機制的基礎和前提。
在這個流程中,中央處理器 (CPU) 的主要任務是解釋和執行最終轉換成機器語言的指令。CPU 由兩個主要部分構成,包括控制單元和算術邏輯單元 (ALU)。
控制單元負責從記憶體中提取指令,並對其進行解碼和執行。
算術邏輯單元 (ALU) 則負責處理算術和邏輯運算。
CPU被稱為計算機的心臟和大腦,它由許多電晶體組成的電子部件構成,與記憶體一起協同工作。CPU接收資料輸入,執行指令並處理資訊。它還與輸入/輸出(I/O)裝置進行通訊,這些裝置向CPU傳送資料並從CPU接收資料。
從功能的角度來看,CPU的內部由暫存器、控制器、運算器和時鐘四個部分組成,並且這些部分之間透過電訊號進行相互連線。
- 暫存器是一種高速儲存器,用於暫時儲存指令、資料和中間結果。
- 控制器負責從記憶體中提取指令,並將其解碼為操作訊號,以控制其他部件的工作。
- 運算器則負責執行算術和邏輯運算,包括加法、減法、乘法、除法和比較等操作。
- 時鐘是CPU的主時鐘,用於同步各個部件的操作,確保它們按照正確的順序和時序執行。透過這些部分的協同工作,CPU能夠高效地執行各種計算任務。
CPU可以被分為三個主要部分,即運算單元、資料單元和控制單元。
運算單元主要負責進行各種計算操作,如加法、位移等。然而,運算單元並不知道應該計算哪些資料,也不知道計算結果應該存放在哪裡。
如果每次計算的資料都需要透過匯流排傳輸到記憶體中,這將導致非常低效。因此,資料單元的存在就變得必要了。資料單元包括CPU內部的快取和暫存器組,雖然空間較小,但速度非常快,可以暫時儲存資料和計算結果。
有了資料存放的地方和計算的地方,還需要一個指揮中心來決定具體要進行哪些計算操作,這就是控制單元。控制單元充當統一的指揮中心,它可以獲取下一條指令,並執行該指令。這條指令將指導運算單元從資料單元中取出特定的資料,進行計算,並將結果放回資料單元的相應位置。透過這樣的指令執行過程,CPU能夠高效地進行各種計算任務。
CPU的控制單元包含一個指令指標暫存器,它儲存著下一條指令在記憶體中的地址。控制單元的工作是不斷地將程式碼段中的指令載入進來,並將其放入指令暫存器中。
每條指令可以分為兩個部分:操作型別(如加法或位移)和運算元據。為了執行這條指令,控制單元將操作型別傳遞給運算單元,將運算元據傳遞給資料單元。
資料單元根據資料的地址從資料段中讀取資料,並將其儲存在資料暫存器中,以便參與運算。運算單元執行完運算後,將結果暫時儲存在資料單元的資料暫存器中。最後,透過指令將資料寫回記憶體中的資料段。
或許你會好奇,上述的操作都是針對程式 A 的指令進行的,那程式 B 呢?CPU 內部有兩個專門儲存當前處理程式的程式碼段起始地址和資料段起始地址的暫存器。當執行程式 A 的指令時,這些暫存器儲存著程式 A 的資訊。而當切換到程式 B 時,CPU 會更新這些暫存器的值,這樣就能執行程式 B 的指令了。這個切換過程被稱為程式切換(Process Switch)。
另外,你可能也會注意到,CPU 和記憶體之間的資料傳輸是透過匯流排進行的。匯流排主要有兩類資料,一類是地址資料,即指示我想要訪問記憶體中的哪個位置的資料。這類匯流排被稱為地址匯流排(Address Bus)。另一類是真正的資料,即要傳輸的資料。這類匯流排被稱為資料匯流排(Data Bus)。
地址匯流排的位數決定了能夠訪問的記憶體地址範圍有多廣。例如,如果地址匯流排只有兩位,那麼 CPU 就只能識別 00、01、10、11 這四個位置,超過這個範圍就無法區分。地址匯流排位數越多,能夠訪問的位置就越多,CPU 能夠管理的記憶體範圍也就越廣。例如,32位的地址匯流排可以定址2的32次方(約為4GB)個記憶體位置。因此,32位的地址匯流排可以識別並訪問的記憶體位置範圍是從0到2的32次方減1。
需要注意的是,地址匯流排的位數與CPU的資料位數是不同的。CPU的資料位數決定了它一次能夠處理的資料量,而地址匯流排的位數決定了它能夠定址的記憶體位置範圍。
而資料匯流排的位數決定了每次能夠傳輸多少個資料。例如,如果資料匯流排只有兩位,那麼 CPU 每次只能傳輸兩位資料。如果要傳輸八位資料,就需要進行四次傳輸。資料匯流排位數越多,每次傳輸的資料量就越大,訪問速度也就越快。
總結
計算機指令是CPU能夠理解的語言,也稱為機器語言。不同的CPU支援不同的指令集,對應不同的組合語言和機器碼。MIPS指令集是一種常用的指令集。
CPU執行指令的過程包括指令的解碼和執行。CPU內部由控制單元、算術邏輯單元和資料單元組成,它們協同工作來執行指令。控制單元負責指令的解碼和操作訊號的生成,算術邏輯單元負責執行計算操作,資料單元用於儲存資料和計算結果。
CPU和記憶體之間的資料傳輸透過地址匯流排和資料匯流排進行。地址匯流排決定了CPU能夠定址的記憶體位置範圍,資料匯流排決定了每次能夠傳輸的資料量。