CPU對(duì)每個(gè)程序員來(lái)說,是個(gè)既熟悉又陌生的東西?
如果你只知道CPU是中央處理器的話,那可能對(duì)你并沒有什么用,那么作為程序員的我們,必須要搞懂的就是CPU這家伙是如何運(yùn)行的,尤其要搞懂它里面的寄存器是怎么一回事,因?yàn)檫@將讓你從底層明白程序的運(yùn)行機(jī)制。
隨我一起,來(lái)好好認(rèn)識(shí)下CPU這貨吧
把CPU掰開來(lái)看
對(duì)于CPU來(lái)說,我們首先就要搞明白它是怎么回事,也就是它的內(nèi)部構(gòu)造,當(dāng)然,CPU那么牛的一個(gè)東西,構(gòu)造一定是極其復(fù)雜的,畢竟是超高科技玩意,所以啊,我們今天說的組成什么的,都是指的主要的,對(duì)我們程序員有用的,需要了解的那一部分,切莫抬杠哦
首先嘞,我希望你先記住這句話:
CPU所負(fù)責(zé)的就是解釋和運(yùn)行最終轉(zhuǎn)換成機(jī)器語(yǔ)言的程序內(nèi)容
另外啊,說起CPU,一定離不開內(nèi)存,在今天的介紹中,也會(huì)簡(jiǎn)單的說說內(nèi)存,因?yàn)楹笃谝矔?huì)單獨(dú)出一篇講解下內(nèi)存,畢竟了解這些對(duì)我們程序員來(lái)說很重要的,所以CPU和內(nèi)存經(jīng)常在一塊來(lái)講,他們其實(shí)是有很多的晶體管組成的,一般稱他們?yōu)镮C,也就是集成電路的意思。
接下來(lái)我們就來(lái)看看CPU的組成,注意我之前說的,這里說的組成一般是指的主要部分,畢竟CPU結(jié)構(gòu)復(fù)雜。
我們需要知道的CPU結(jié)構(gòu)
重點(diǎn)需要關(guān)注寄存器
運(yùn)算器
字面意思理解就是跟運(yùn)算有關(guān)的,簡(jiǎn)單說就是負(fù)責(zé)運(yùn)算從內(nèi)存讀取到寄存器中的數(shù)據(jù),可以看作一個(gè)數(shù)據(jù)加工廠,就是對(duì)寄存器中的數(shù)據(jù)做運(yùn)算,這些運(yùn)算包含基本的算術(shù)和邏輯運(yùn)算。
然后對(duì)于運(yùn)算器來(lái)說,我們要了解其中的幾個(gè)重要角色,接下來(lái)我會(huì)挨個(gè)介紹:
算術(shù)邏輯單元(ALU)
這個(gè)是運(yùn)算器中重要的一個(gè)組成,主要負(fù)責(zé)的就是對(duì)數(shù)據(jù)的處理,從而實(shí)現(xiàn)對(duì)數(shù)據(jù)的算術(shù)和邏輯運(yùn)算
累計(jì)寄存器(AC)
通常叫做累計(jì)器,是一個(gè)通用寄存器,這個(gè)有啥用呢?上面說的ALU,當(dāng)ALU處理完算術(shù)運(yùn)算或者邏輯運(yùn)算之后,會(huì)得到一個(gè)結(jié)果,這個(gè)結(jié)果就會(huì)保存在AC中
數(shù)據(jù)緩沖寄存器(DR)
這個(gè)DR也是存放數(shù)據(jù)的,存放的主要是從內(nèi)存讀取過來(lái)的數(shù)據(jù),會(huì)暫時(shí)存放在這個(gè)DR中,這里就相當(dāng)于內(nèi)存和CPU之間做數(shù)據(jù)傳送的一個(gè)中轉(zhuǎn)站,為啥會(huì)有這個(gè),大家都是到CPU和內(nèi)存的速度是有很大差別的,中間引入一個(gè)DR,一定程度上起到了速度上的緩沖作用,不至于速度相差太猛
狀態(tài)條件寄存器(PSW)
這個(gè)貌似有點(diǎn)不好理解,首先寄存器還是保存數(shù)據(jù)的,所以PSW自然也是保存某一類數(shù)據(jù)的,它保存的主要是由算術(shù)指令和邏輯指令運(yùn)行或者測(cè)試的結(jié)果建立的各種條件碼內(nèi)容,一般分為狀態(tài)標(biāo)志和控制標(biāo)志,知道就行
我們需要了解以上的這幾個(gè)組成部分,這都是運(yùn)算器的核心,另外需要特別說一下的就是它們每一個(gè)其實(shí)都有一個(gè)英文縮寫,比如ALU就是算術(shù)邏輯單元的意思,為啥要說這個(gè)嘞,因?yàn)橛⑽目s寫畢竟簡(jiǎn)便而且有逼格,所以我們一般交流的時(shí)候會(huì)說ALU而不是算術(shù)邏輯單元,因此,記住他們的縮寫也很重要哦。
不然跟別人交流起來(lái)的話,別人一出口就是ALU,DR啥的,你很容易跟不上節(jié)奏啊。
對(duì)CPU中的運(yùn)算器有個(gè)基本認(rèn)識(shí)以后,我們?cè)賮?lái)看看另外一個(gè)重要組成 控制器
控制器
控制控制,也就是起到一個(gè)控制作用,上面介紹的運(yùn)算器只是起到了運(yùn)算的功能,但是控制器就比較牛,它是控制整個(gè)CPU的工作,對(duì)于控制器,一般要能夠保證程序的正確執(zhí)行以及能夠處理異常事件
同樣的,對(duì)于控制器來(lái)說,我們需要重點(diǎn)關(guān)注如下幾個(gè):
指令寄存器(IR)
寄存器是保存東西的,指令寄存器自然就是保存指令的,也就是說CPU要執(zhí)行一條指令的話,需要先把指令從內(nèi)存上讀取,然后放到我們上面說的數(shù)據(jù)緩沖寄存器中,之后再?gòu)腄R放到IR中,接著嘞,會(huì)有一個(gè)叫做指令譯碼器的東西根據(jù)IR的內(nèi)容生成很多的微操作指令,從而去控制其他部件已完成相應(yīng)的功能
程序計(jì)數(shù)器(PC)
這個(gè)學(xué)過Java內(nèi)存結(jié)構(gòu)的應(yīng)該了解,它保存著下一條要執(zhí)行的指令,也就是說當(dāng)一個(gè)程序要執(zhí)行的時(shí)候,會(huì)把這個(gè)程序的起始地址存到這個(gè)PC中,如果這個(gè)指令被執(zhí)行的話也不用擔(dān)心,CPU會(huì)自動(dòng)修改,使得PC存放下一條要執(zhí)行的指令
地址寄存器(AR)
這個(gè)就是保存著CPU訪問內(nèi)存上的那一塊內(nèi)存的內(nèi)存地址,為啥要保存這個(gè),因?yàn)镃PU和內(nèi)存速度相差比較大,所以CPU要保存著正在訪問的那塊內(nèi)存的地址,直到內(nèi)存的讀寫操作完成,不然,找不到之前訪問的是哪個(gè)內(nèi)存單元了啊
指令譯碼器(ID)
簡(jiǎn)單點(diǎn)就是對(duì)指令做分析的,看看你這個(gè)指令要干啥
不知道你有沒有發(fā)現(xiàn),我們上面無(wú)論再介紹運(yùn)算器還是控制器的時(shí)候,都大量提及寄存器,這足以說明寄存器的重要性,不是有句話說其實(shí)CPU就是寄存器的集合體,不過在說寄存器之前,我們還是很有必要先來(lái)簡(jiǎn)單的看看內(nèi)存。
簡(jiǎn)單說下內(nèi)存(以后會(huì)單獨(dú)說)
CPU和內(nèi)存總是分不開的,這里簡(jiǎn)單對(duì)內(nèi)存坐下介紹,方便對(duì)CPU的理解,內(nèi)存自然而然是存儲(chǔ)部件,存儲(chǔ)的是啥呢?一般來(lái)說,就是數(shù)據(jù)和指令,而且我們常說的內(nèi)存指的就是電腦中的內(nèi)存條,就是用來(lái)存儲(chǔ)程序啊,數(shù)據(jù)啊,指令啊這些東西。
形象點(diǎn)說,其實(shí)內(nèi)存可以看作一個(gè)個(gè)的小格子,每個(gè)格子都是用來(lái)存儲(chǔ)數(shù)據(jù)的,而且每個(gè)格子還有編號(hào),也就是內(nèi)存地址,根據(jù)它可與拿到對(duì)應(yīng)內(nèi)存存儲(chǔ)的數(shù)據(jù),還需要知道的就是,如果斷電的話,內(nèi)存中的數(shù)據(jù)會(huì)被清除的。
CPU的大部分都是寄存器
上面說了CPU其實(shí)由運(yùn)算器和控制器兩大部分組成,其實(shí)無(wú)論是運(yùn)算器還是控制器,都離不開寄存器,可以說,CPU就是寄存器的天下,因此,對(duì)于CPU,一定要掌握好寄存器,CPU做的一些運(yùn)算其實(shí)就是通過寄存器來(lái)實(shí)現(xiàn)的,可以看看這篇文章:一個(gè)程序在計(jì)算機(jī)中是怎么運(yùn)行的?
先記住一句話:
我們使用的Java,python這些都是高級(jí)語(yǔ)言,編寫的程序最終會(huì)轉(zhuǎn)成機(jī)器語(yǔ)言,之后就會(huì)進(jìn)入CPU運(yùn)算,實(shí)質(zhì)就是通過CPU內(nèi)部的寄存器來(lái)做相應(yīng)的處理的
寄存器
這個(gè)是我們需要掌握的,寄存器這玩意,不同的CPU中含有的寄存器數(shù)量和種類都不同,不過大體有如下幾種寄存器,按照功能來(lái)分的
另外其實(shí)就可以把CPU理解為是寄存器的集合體,然后你需要知道程序計(jì)數(shù)器,累加寄存器,標(biāo)志寄存器,指令寄存器和棧寄存器只有一個(gè),其他的寄存器一般會(huì)有多個(gè)。
說說這個(gè)程序計(jì)數(shù)器
為啥要說這個(gè),因?yàn)檫@玩意決定著程序的執(zhí)行流程,我們進(jìn)一步來(lái)看看
比如看這個(gè),這個(gè)表示的是兩個(gè)數(shù)相加的操作,關(guān)于這個(gè)操作涉及到的數(shù)據(jù)和指令都保存在了內(nèi)存中,而且每個(gè)數(shù)據(jù)和指令所在的內(nèi)存單元都是有編號(hào)的,也就是內(nèi)存地址,就是圖中0100,0101那些,自上而下就是該操作的執(zhí)行順序。
上面也提到過,程序計(jì)數(shù)器是保存程序執(zhí)行的指令的,準(zhǔn)確說保存的是程序執(zhí)行指令的地址值,怎么理解呢?也就是說程序的每一步操作,底層來(lái)說都是有一系列指令對(duì)應(yīng)著的,這些指令就是表明這一步該怎么操作,比如a+b這個(gè)操作,加載進(jìn)內(nèi)存后就是對(duì)應(yīng)著一系列的指令。
首先就是一個(gè)指令,表明要把a(bǔ)這個(gè)數(shù)值做相加操作,需要先把a(bǔ)保存到累加寄存器,而這個(gè)指令被保存在內(nèi)存中的一個(gè)內(nèi)存單元中,這個(gè)內(nèi)存地址比如說就是0100,而此時(shí)程序計(jì)數(shù)器就是保存的這個(gè)0100內(nèi)存地址,要執(zhí)行程序的時(shí)候,CPU去看看程序計(jì)數(shù)器保存的第一個(gè)地址,發(fā)現(xiàn)是0100,然后去內(nèi)存這個(gè)0100的位置,看看保存的是啥,一看是一個(gè)指令,分析指令,原來(lái)是要把0105地址中的值保存到累加寄存器中,然后就開始干活……
所以說啊,程序計(jì)數(shù)器其實(shí)我是決定管理程序的執(zhí)行流程的
CPU是如何做比較的
這個(gè)也需要了解一下,CPU的比較其實(shí)就是再內(nèi)部做減法運(yùn)算,什么意思呢?比如要比較a和b,就是再內(nèi)部做一個(gè)a-b的操作,然后依據(jù)得到的結(jié)果來(lái)對(duì)a和b做比較,這里面肯定是要借助寄存器來(lái)完成,比如得到的結(jié)果就會(huì)放到標(biāo)志寄存器中。
CPU做的事其實(shí)很簡(jiǎn)單
我們?cè)谥暗奈恼抡f過,CPU其實(shí)主要就是干如下的四件事情:
從內(nèi)存中讀取數(shù)據(jù),然后放到寄存器中
把寄存器中的數(shù)據(jù)寫入到內(nèi)存
進(jìn)行數(shù)學(xué)運(yùn)算和邏輯運(yùn)算(加減乘除,AND,OR)
依據(jù)相應(yīng)的條件進(jìn)行跳轉(zhuǎn),執(zhí)行其他指令(一條指令跳轉(zhuǎn)到另外一條指令)
我們知道,CPU是依據(jù)指令做事情的,為什么CPU只做上面的四件事情,主要就是看CPU 能執(zhí)行的機(jī)器語(yǔ)言指令有哪些,主要就是如下這些
這么一看,CPU能干的事也沒有那么復(fù)雜啊。
CPU指令執(zhí)行過程
經(jīng)過上面的講解,我們應(yīng)該知道CPU就是看指令做事情的,那么關(guān)于指令,CPU又是怎么操作的呢? 我們要知道的是幾乎所有的馮·諾伊曼型計(jì)算機(jī)的CPU,其工作都可以分為5個(gè)步驟:取指令、指令譯碼、執(zhí)行指令、訪問取數(shù)、結(jié)果寫回。
可能你不懂了,沒啥,其實(shí)不就是這五個(gè)步驟嘛,搞清楚他們不就ok,接下來(lái)咱們來(lái)看看:
第一:取指令
字面意思很好理解啊,不就是拿到需要的指令嘛,那么指令在哪嘞,必須是在內(nèi)存啊,也就是需要從內(nèi)存中取出我們需要的指令,然后干嘛,不就是把指令放到CPU中的寄存器嘛,這個(gè)取指令就是這么一個(gè)過程。
第二:指令譯碼
這個(gè)是不是很快想到我們上面說的指令譯碼器,這個(gè)不就是對(duì)上一步拿到的指令做分析嘛,干嘛要分析,我得看看你這個(gè)指令到底要干啥啊,不然CPU怎么干活嘞
第三:執(zhí)行指令
這個(gè)不就更好理解了,就是開始干活啦,實(shí)現(xiàn)相應(yīng)的功能了
第四:訪問取數(shù)
直觀上好像沒有那么好理解,其實(shí)啊,說的就是,我們根據(jù)上面的操作,有可能需要從內(nèi)存中去拿數(shù)據(jù),啥意思嘞,要知道,內(nèi)存存放的是數(shù)據(jù)和指令,比如執(zhí)行a+b的操作,我們得到相加的指令,對(duì)于a和b都是操作數(shù),它們也是存放在內(nèi)存中的,是不是也需要去內(nèi)存中去拿到它們
看上面那個(gè)圖,0100對(duì)應(yīng)的指令是不是要去0105對(duì)應(yīng)的地址中去拿數(shù)據(jù)123,這不就是訪問取數(shù)嘛。
第五:結(jié)果寫回
這又是啥,經(jīng)過上面那么些個(gè)步驟,做的運(yùn)算肯定得有結(jié)果啊,這結(jié)果咋弄,你不得保存在哪啊,通常是保存在CPU內(nèi)部的寄存器中,一般是標(biāo)志寄存器,這不是就是結(jié)果寫回嘛
好啦,到這里,關(guān)于CPU的知識(shí)咱們就介紹的差不多了,當(dāng)然,CPU的知識(shí)遠(yuǎn)遠(yuǎn)不止如此,但是作為程序員的你,最起碼也得知道這些啊。