CPU和內存是由許多晶體管組成的電子部件,一般稱爲IC(Integrated Circuit,集成電路)。從功能方面來看,CPU的內部由寄存器,控制器,運算器和時鐘四部分構成,各部分之間由電流信號相互連通。程序員
寄存器:可用來暫存指令,數據等處理對象,能夠將其看作是內存的一種。根據種類的不一樣,一個CPU內部會有20~100個寄存器。編程
控制器:負責把內存上的指令,數據等讀入寄存器,並根據指令的執行結果來控制整個計算機。數組
運算器:負責運算從內存讀入寄存器的數據。編程語言
時鐘:負責發出CPU開始計時的時鐘信號。不過,也有些計算機的時鐘位於CPU的外部。函數
程序是把寄存器做爲對象來描述的ui
使用高級語言編寫的程序會在編譯後轉化成機器語言,而後經過CPU內部的寄存器來處理。不一樣類型的CPU,其內部寄存器的數量,種類以及寄存器存儲的數值範圍都是不一樣的。根據功能的不一樣,咱們能夠將寄存器大體劃分爲八類。操作系統
累加寄存器:存儲執行運算的數據和運算後的數據。對象
標誌寄存器:存儲運算處理後的CPU的狀態。blog
程序計數器:存儲下一條指令所在內存的地址。索引
基址寄存器:存儲數據內存的起始地址。
變址寄存器:存儲基址寄存器的相對地址。
通用寄存器:存儲任意數據。
指令寄存器:存儲指令。CPU內部使用,程序員沒法經過程序對該寄存器進行讀寫操做。
棧寄存器:存儲棧區域的起始地址。
其中,程序計數器,累加寄存器,標誌寄存器,指令寄存器和棧寄存器都只有一個,其餘的寄存器通常有多個。
地址0100是程序運行的開始位置。Windows等操做系統把程序從硬盤複製到內存後,會將程序計數器(CPU寄存器的一種)設定爲0100,而後程序開始運行。CPU每執行一個指令,程序計數器的值就會自動加1。例如,CPU執行0100地址的指令後,程序計算器的值就變成0101(當執行的指令佔據多個內存地址時,增長與指令長度相應的數值)。而後,CPU的控制器就會參照程序計數器的數值,從內存中讀取命令並執行。也就是說,程序計數器決定着程序的流程。
程序的流程分爲順序執行, 條件分支和循環三種。順序執行是指按照地址內容的順序執行指令。條件分支是指根據條件執行任意地址的指令。循環是指重複執行同一地址的指令。
上圖表示把內存中存儲的數值的絕對值輸出到顯示器的程序的內存狀態。程序運行的開始位置是0100地址。隨着程序計數器數值的增長,當達到0102地址時,若是累加寄存器的值是正數,則執行跳轉指令(jump指令)跳轉到0104地址。此時,因爲累加寄存器的數值是123,爲正數,所以0103地址的指令被跳過,程序的流程直接跳轉到0104地址。也就是說,「跳轉到0104地址」這個指令間接執行了「將程序計數器設定成0104地址」這個操做。
條件分支和循環中使用的跳轉指令,會參照當前執行的運算結果來判斷是否跳轉。不管當前累加寄存器的運算結果是負數,零仍是正數,標誌寄存器都會將其保存。CPU在進行運算時,標誌寄存器的數值會根據運算結果自動設定。條件分支在跳轉指令前會進行比較運算。至因而否執行跳轉指令,則由CPU在參考標誌寄存器的數值後進行判斷。運算結果的正,零,負三種狀態由標誌寄存器的三個位表示。如圖:
標誌寄存器的第一個字節位,第二個字節位和第三個字節位的值爲1時,表示運算結果分別爲正數、零和負數。
CPU執行比較的機制頗有意思,所以請你們務必牢記。例如,假設要比較累加寄存器中存儲的XXX值和通用寄存器中存儲的YYY值,執行比較的指令後,CPU的運算裝置就會在內部(暗中)進行XXX-YYY的減法運算。而不管減法運算的結果是正數、零仍是負數,都會保存在標誌寄存器中。程序中的比較指令,就是在CPU內部作減法運算。
哪怕是高級語言編寫的程序,函數調用處理也是經過把程序計數器的值設定成函數的存儲地址來實現的。
上圖是給變量a和b分別代入123和456後,將其賦值給參數(parameter)來調用MyFunc函數的C語言程序。圖中地址是將C語言編譯成機器語言後運行的地址。因爲1行C語言程序在編譯後一般會變成多行的機器語言,因此圖中的地址是離散的。
此外,經過跳轉指令把程序計數器的值設定成0260也可實現調用MyFunc函數。函數的調用原點(0132地址)和被調用函數(0260地址)之間的數據傳遞,能夠經過內存或寄存器來實現。
機器語言的call指令和return指令可以解決這個問題。函數調用使用的是call指令,而不是跳轉指令。在將函數的入口地址設定到程序計數器以前,call指令會把調用函數後要執行的指令地址存儲在名爲棧的主存內。函數處理完畢後,再經過函數的出口來執行return命令。return的功能是把保持在棧中的地址設定到程序計數器中。如圖所示,MyFunc函數被調用以前,0514地址保持在棧中。MyFunc函數的處理完畢後,棧中的0514地址就會被讀取出來,而後再被設定到程序計數器中。
如圖所示,出現的基址寄存器和變址寄存器。經過這兩個寄存器,咱們能夠對主內存上特定的內存區域進行劃分,從而實現相似於數組的操做。
首先,用十六進制數將計算機內存上00000000~FFFFFFFF的地址分出來。那麼,凡是該範圍的內存區域,只要是有一個32位的寄存器,便可查看所有的內存地址。但若是想要像數組那樣分割特定的內存區域以達到連續查看的目的,使用兩個寄存器會更方便些。例如查看10000000地址~1000FFFF地址時,能夠將10000000存入基址寄存器,並使變址寄存器的值在0000000~0000FFFF變化。CPU則會把基址寄存器+變址寄存器的值解釋爲實際查看的內存地址。變址寄存器的值就至關於高級編程語言程序中數組的索引功能。