|
點(diǎn)擊左上方藍(lán)色“一口Linux”,選擇“設(shè)為星標(biāo)”
第一時(shí)間看干貨文章
?【干貨】嵌入式驅(qū)動(dòng)工程師學(xué)習(xí)路線(xiàn)?【干貨】Linux嵌入式知識(shí)點(diǎn)-思維導(dǎo)圖-免費(fèi)獲取?【就業(yè)】一個(gè)可以寫(xiě)到簡(jiǎn)歷的基于Linux物聯(lián)網(wǎng)綜合項(xiàng)目?【就業(yè)】找工作簡(jiǎn)歷模版
uhmsyqhphoy640840141.gif (555.24 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
uhmsyqhphoy640840141.gif
2024-9-14 18:56 上傳
作為一名程序員,與計(jì)算機(jī)打交道的日子不計(jì)其數(shù),不管你玩硬件還是做軟件,你的世界自然都少不了計(jì)算機(jī)最核心的 —— CPU。01CPU是什么?CPU與計(jì)算機(jī)的關(guān)系就相當(dāng)于大腦和人的關(guān)系,它是一種小型的計(jì)算機(jī)芯片,通常嵌入在電腦的主板上。CPU的構(gòu)建是通過(guò)在單個(gè)計(jì)算機(jī)芯片上放置數(shù)十億個(gè)微型晶體管來(lái)實(shí)現(xiàn)。這些晶體管使它能夠執(zhí)行運(yùn)行存儲(chǔ)在系統(tǒng)內(nèi)存中的程序所需的計(jì)算,所以,也可以說(shuō)CPU決定了你電腦的計(jì)算能力。02CPU實(shí)際做什么?CPU的工作核心是從程序或應(yīng)用程序中獲取指令并且執(zhí)行計(jì)算。這個(gè)過(guò)程一共有三個(gè)關(guān)鍵階段:提取,解碼和執(zhí)行。CPU先從系統(tǒng)的RAM中提取指令,隨后解碼該指令的實(shí)際內(nèi)容,最后再由CPU的相關(guān)部分執(zhí)行該指令。03CPU的內(nèi)部結(jié)構(gòu)剛才提到了很多CPU的重要性,那么CPU的內(nèi)部結(jié)構(gòu)是什么呢?又是由什么組成的呢?下圖展示了一般程序的運(yùn)行流程(以C語(yǔ)言為例),一般來(lái)說(shuō),了解程序的運(yùn)行流程是掌握程序運(yùn)行機(jī)制的基礎(chǔ)和前提。
nlgwl2qo2xv640840241.jpg (123.21 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
nlgwl2qo2xv640840241.jpg
2024-9-14 18:56 上傳
在這個(gè)流程中,CPU負(fù)責(zé)解釋和運(yùn)行最終轉(zhuǎn)換成機(jī)器語(yǔ)言的內(nèi)容,CPU主要由兩部分構(gòu)成:控制單元和算數(shù)邏輯單元(ALU)。控制單元:從內(nèi)存中提取指令并解碼執(zhí)行;
算數(shù)邏輯單元(ALU):處理算數(shù)和邏輯運(yùn)算。
CPU和內(nèi)存都是由許多晶體管組成的電子部件,可以把它比作計(jì)算機(jī)的心臟和大腦。它能夠接收數(shù)據(jù)輸入、執(zhí)行指令并且處理相關(guān)信息,它與輸入/輸出(I/O)設(shè)備進(jìn)行通信,這些設(shè)備向 CPU 發(fā)送數(shù)據(jù)和從 CPU 接收數(shù)據(jù)。從功能上來(lái)看,CPU的內(nèi)容是由寄存器、控制器、運(yùn)算器和時(shí)鐘四部分組成的,各個(gè)部分之間通電信號(hào)來(lái)連通。接下來(lái)簡(jiǎn)單介紹一下內(nèi)存,為什么說(shuō)到CPU需要講一下內(nèi)存呢?因?yàn)閮?nèi)存是與CPU進(jìn)行溝通的橋梁,計(jì)算機(jī)中所有程序的運(yùn)行都在內(nèi)存中得到運(yùn)行的。內(nèi)存一般又被稱(chēng)為主存,它的作用是存放CPU中的運(yùn)算數(shù)據(jù),以及與硬盤(pán)等外部存儲(chǔ)設(shè)備交換的數(shù)據(jù)。CPU會(huì)在計(jì)算機(jī)運(yùn)轉(zhuǎn)時(shí),把需要運(yùn)算的數(shù)據(jù)調(diào)到主存中進(jìn)行運(yùn)算。在運(yùn)算完成之后,CPU將結(jié)果傳送出來(lái),主存的運(yùn)行也決定了計(jì)算機(jī)的穩(wěn)定運(yùn)行。主存一般通過(guò)控制芯片與CPU相連,由可讀寫(xiě)的元素構(gòu)成,每個(gè)字節(jié)都有一個(gè)地址編號(hào)。CPU通過(guò)地址從主存中讀取數(shù)據(jù)和指令,也可以根據(jù)地址寫(xiě)入數(shù)據(jù),注意一點(diǎn):當(dāng)計(jì)算機(jī)關(guān)機(jī)時(shí),內(nèi)存中的指令和數(shù)據(jù)也會(huì)被清除。04CPU是寄存器的集合體在CPU的四個(gè)結(jié)構(gòu)中,寄存器的重要性遠(yuǎn)遠(yuǎn)高于其余三個(gè),為什么這么說(shuō)?因?yàn)槌绦蛲ǔJ前鸭拇嫫髯鳛閷?duì)象來(lái)進(jìn)行描述的。而說(shuō)到寄存器,就不得不說(shuō)到匯編語(yǔ)言,說(shuō)到匯編語(yǔ)言,就不得不說(shuō)到高級(jí)語(yǔ)言,說(shuō)起高級(jí)語(yǔ)言也就不得不提及語(yǔ)言的概念。05計(jì)算機(jī)語(yǔ)言人和人之間最古老和直接的溝通媒介是語(yǔ)言,但是和計(jì)算機(jī)溝通,就必須按照計(jì)算機(jī)指令來(lái)交換,其中就涉及到語(yǔ)言的問(wèn)題。最早,為了解決計(jì)算機(jī)和人類(lèi)的交流的問(wèn)題,出現(xiàn)了匯編語(yǔ)言。但是匯編語(yǔ)言晦澀難懂,所以又出現(xiàn)了像是C、C++、Java的這種高級(jí)語(yǔ)言,因此計(jì)算機(jī)語(yǔ)言一般分為低級(jí)語(yǔ)言和高級(jí)語(yǔ)言。使用高級(jí)語(yǔ)言編寫(xiě)的程序,經(jīng)過(guò)編譯轉(zhuǎn)換成機(jī)器語(yǔ)言后才能運(yùn)行,而匯編語(yǔ)言經(jīng)過(guò)匯編器才能轉(zhuǎn)換為機(jī)器語(yǔ)言。06匯編語(yǔ)言我們先來(lái)看一段采用匯編語(yǔ)言表示的代碼清單:
0owve0r2q1i640840341.jpg (51 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
0owve0r2q1i640840341.jpg
2024-9-14 18:56 上傳
這是采用匯編語(yǔ)言編寫(xiě)程序的一部分,匯編語(yǔ)言采用助記符來(lái)編寫(xiě)程序,每個(gè)原本是電信號(hào)的機(jī)器語(yǔ)言指令會(huì)有一個(gè)與其對(duì)應(yīng)的助記符。比如,mov,add分別是數(shù)據(jù)的存儲(chǔ)(move)和相加(addition)的簡(jiǎn)寫(xiě)。匯編語(yǔ)言和機(jī)器語(yǔ)言一一對(duì)應(yīng),這點(diǎn)和高級(jí)語(yǔ)言不同,我們通常把匯編語(yǔ)言編寫(xiě)的程序轉(zhuǎn)換為機(jī)器語(yǔ)言的這個(gè)過(guò)程,稱(chēng)之為匯編。與之相反,將機(jī)器語(yǔ)言轉(zhuǎn)化為匯編語(yǔ)言的過(guò)程稱(chēng)之為反匯編。匯編語(yǔ)言可以幫助你理解計(jì)算機(jī)做了什么工作,機(jī)器語(yǔ)言級(jí)別的程序通過(guò)寄存器來(lái)處理,上面代碼中的eax,ebp都是表示的寄存器,它們是CPU內(nèi)部寄存器的名稱(chēng)。因此,可以說(shuō) CPU 是一系列寄存器的集合體。一般,在內(nèi)存中的存儲(chǔ)通過(guò)地址編號(hào)來(lái)表示,寄存器的種類(lèi)是通過(guò)名字來(lái)區(qū)分。那些不同類(lèi)型的CPU,其內(nèi)部寄存器的種類(lèi)、數(shù)量以及寄存器存儲(chǔ)的數(shù)值范圍也都是不同的。不過(guò),根據(jù)功能的不同,我們可以將寄存器劃分為下面幾類(lèi):
2qv4irfknmm640840441.png (164.35 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
2qv4irfknmm640840441.png
2024-9-14 18:56 上傳
其中,程序計(jì)數(shù)器、標(biāo)志寄存器、累加寄存器、指令寄存器和棧寄存器只有一個(gè),其他寄存器一般有好幾個(gè)。07
程序計(jì)數(shù)器程序計(jì)數(shù)器是用來(lái)存儲(chǔ)下一條指令所在單元的地址。程序在執(zhí)行時(shí),PC的初值作為程序第一條指令的地址,在順序執(zhí)行程序時(shí),控制器先按照程序計(jì)數(shù)器所指出的指令地址,從內(nèi)存中取出一條指令,隨后分析和執(zhí)行該指令,并同時(shí)將PC的值加1指向下一條要執(zhí)行的指令。
我們可以通過(guò)一個(gè)事例來(lái)仔細(xì)看一下程序計(jì)數(shù)器的執(zhí)行過(guò)程:
vh2q4h3ef3y640840541.jpg (173.18 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
vh2q4h3ef3y640840541.jpg
2024-9-14 18:56 上傳
這是一段進(jìn)行相加的操作,程序啟動(dòng),在經(jīng)過(guò)編譯解析后,會(huì)經(jīng)由操作系統(tǒng)把硬盤(pán)中的程序復(fù)制到內(nèi)存中。以上示例程序,就是將123和456執(zhí)行相加的操作,隨后將結(jié)果輸出到顯示器上,因?yàn)槭褂脵C(jī)器語(yǔ)言很難描述,所以這些都是經(jīng)過(guò)翻譯后的結(jié)果。事實(shí)上,每個(gè)指令和數(shù)據(jù)都有可能分布在不同的地址上,但是為了更好的說(shuō)明,就把組成一條指令的內(nèi)存和數(shù)據(jù)放在了一個(gè)內(nèi)存地址上。地址0100是程序運(yùn)行的起始位置,Windows等操作系統(tǒng)把程序從硬盤(pán)復(fù)制到內(nèi)存以后,就會(huì)將程序計(jì)數(shù)器作為設(shè)定為起始位置0100,然后再執(zhí)行程序,每次執(zhí)行一條指令后,程序計(jì)數(shù)器的數(shù)值就會(huì)增加1,或者是直接指向下一條指令的地址。隨后,CPU會(huì)根據(jù)程序計(jì)數(shù)器的數(shù)值,從內(nèi)存中讀取命令并且執(zhí)行,換言之,程序計(jì)數(shù)器控制著程序的流程。08
條件分支和循環(huán)機(jī)制小伙伴們都學(xué)過(guò)高級(jí)語(yǔ)言,高級(jí)語(yǔ)言匯總的條件控制流程主要分為順序執(zhí)行、條件分支、循環(huán)判斷三種。順序執(zhí)行是按照地址的內(nèi)容順序的執(zhí)行命令。條件分支是根據(jù)條件執(zhí)行任意地址的指令。循環(huán)是重復(fù)執(zhí)行同一地址的指令。一般情況下,順序執(zhí)行的情況較簡(jiǎn)單,每次執(zhí)行一條指令程序計(jì)數(shù)器的值就是+1。條件和循環(huán)分支會(huì)使得程序計(jì)數(shù)器的值指向任意的地址,這樣一來(lái),程序就可以返回到上一個(gè)地址來(lái)重復(fù)執(zhí)行同一個(gè)指令,或者跳轉(zhuǎn)到其它任意指令。
下面,我們就以條件分支舉例來(lái)說(shuō)明程序的執(zhí)行過(guò)程:
fxnfkycdera640840641.jpg (159.6 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
fxnfkycdera640840641.jpg
2024-9-14 18:56 上傳
程序的開(kāi)始過(guò)程和順序流程是一樣的,程序的順序流程和開(kāi)始過(guò)程相同。CPU從0100處就開(kāi)始執(zhí)行命令,在0100和0101中都是順序執(zhí)行,PC的值順序+1,執(zhí)行到0102地址的指令時(shí),判斷0106寄存器的數(shù)值大于0,跳轉(zhuǎn)到0104地址的指令,再將數(shù)值輸?shù)斤@示器中,隨后結(jié)束程序,0103的指令就被跳過(guò)了。這和我們程序中的if()判斷相同,在不滿(mǎn)足條件的情況下,指令一般會(huì)直接跳過(guò)。因此,PC的執(zhí)行過(guò)程沒(méi)有直接+1,而是下一條指令的地址。09
標(biāo)志寄存器條件和循環(huán)分支會(huì)使用到 jump(跳轉(zhuǎn)指令),會(huì)根據(jù)當(dāng)前的指令來(lái)判斷是否跳轉(zhuǎn),上面我們提到了標(biāo)志寄存器,無(wú)論當(dāng)前累加寄存器的運(yùn)算結(jié)果是正數(shù)、負(fù)數(shù)還是零,標(biāo)志寄存器都會(huì)將其保存。CPU在進(jìn)行運(yùn)算時(shí),標(biāo)志寄存器的數(shù)值會(huì)根據(jù)當(dāng)前運(yùn)算的結(jié)果自動(dòng)設(shè)定,運(yùn)算結(jié)果的正、負(fù)和零三種狀態(tài)由標(biāo)志寄存器的三個(gè)位表示。標(biāo)志寄存器的第一個(gè)字節(jié)位、第二個(gè)字節(jié)位、第三個(gè)字節(jié)位各自的結(jié)果都為1時(shí),分別代表著正數(shù)、零和負(fù)數(shù)。
h4tvg4oqzd3640840741.jpg (76.81 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
h4tvg4oqzd3640840741.jpg
2024-9-14 18:56 上傳
CPU的執(zhí)行機(jī)制比較有意思,假設(shè)累加寄存器中存儲(chǔ)的XXX和通用寄存器中存儲(chǔ)的YYY做比較,執(zhí)行比較的背后,CPU的運(yùn)算機(jī)制就會(huì)做減法運(yùn)算。而無(wú)論減法運(yùn)算的結(jié)果是正數(shù)、零還是負(fù)數(shù),都會(huì)保存到標(biāo)志寄存器中。結(jié)果為正表示 XXX 比 YYY 大,結(jié)果為零表示 XXX 和 YYY 相等,結(jié)果為負(fù)表示 XXX 比 YYY 小,程序比較的指令,實(shí)際上是在 CPU 內(nèi)部做減法運(yùn)算。10
函數(shù)調(diào)用機(jī)制函數(shù)的調(diào)用和條件分支,循環(huán)機(jī)制有所不同,單純的跳轉(zhuǎn)指令無(wú)法實(shí)現(xiàn)函數(shù)的調(diào)用。函數(shù)的調(diào)用需要在函數(shù)內(nèi)部處理后,處理流程在返回到函數(shù)調(diào)用點(diǎn)(函數(shù)調(diào)用指令的下一個(gè)地址)。函數(shù)的調(diào)用處理是通過(guò)把程序計(jì)數(shù)器的值設(shè)定成函數(shù)的存儲(chǔ)地址來(lái)實(shí)現(xiàn)的。
4btksik1au1640840841.jpg (125 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
4btksik1au1640840841.jpg
2024-9-14 18:56 上傳
zwtkplkejwq640840941.jpg (149.97 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
zwtkplkejwq640840941.jpg
2024-9-14 18:56 上傳
11
通過(guò)地址和索引實(shí)現(xiàn)數(shù)組接下來(lái)是基址寄存器和變址寄存器,通過(guò)這兩個(gè)寄存器,可以對(duì)主存上的特定區(qū)域進(jìn)行劃分,以此實(shí)現(xiàn)類(lèi)似數(shù)組的操作。首先,可以用十六進(jìn)制數(shù)將計(jì)算機(jī)內(nèi)存上的 00000000 - FFFFFFFF 的地址劃分出來(lái)。這樣,凡是該范圍的內(nèi)存地址,只要有一個(gè) 32 位的寄存器,就可以查看全部地址。但是,要是想像數(shù)組那樣,分割特定的內(nèi)存區(qū)域以達(dá)到連續(xù)查看的目的的話(huà),使用兩個(gè)寄存器會(huì)更方便一些,比如,我們用兩個(gè)寄存器來(lái)表示內(nèi)存的值。
u5pkqf1htdn640841041.jpg (115.47 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
u5pkqf1htdn640841041.jpg
2024-9-14 18:56 上傳
這種表示方式很像數(shù)組的構(gòu)造,數(shù)組是指同樣長(zhǎng)度的數(shù)據(jù),在內(nèi)存中進(jìn)行連續(xù)排列的數(shù)據(jù)構(gòu)造。用數(shù)組名表示數(shù)組全部的值,通過(guò)索引來(lái)區(qū)分?jǐn)?shù)組的各個(gè)數(shù)據(jù)元素,例如: a[0] - a[4],[]內(nèi)的 0 - 4 就是數(shù)組的下標(biāo)。
12
CPU指令執(zhí)行過(guò)程那說(shuō)了這么多,CPU到底是怎么一條條的執(zhí)行指令的呢?幾乎全部的馮·諾伊曼型計(jì)算機(jī)的CPU,工作都可以分為5個(gè)階段:取指令、指令譯碼、執(zhí)行指令、訪(fǎng)存取數(shù)、結(jié)果寫(xiě)回。取指令階段就是將內(nèi)存中的指令讀取到CPU中寄存器的過(guò)程,程序寄存器用于存儲(chǔ)下一條指令所在的地址;在取指令完成后,立馬進(jìn)入指令譯碼階段,在指令譯碼階段,指令編碼器按照預(yù)先的指令格式,對(duì)取回的指令進(jìn)行拆分和解釋?zhuān)R(shí)別區(qū)分出不同的指令類(lèi)別和各種獲取操作數(shù)的方法;
執(zhí)行指令階段的任務(wù)是完成指令所規(guī)定的各種操作,具體實(shí)現(xiàn)指令的功能;訪(fǎng)問(wèn)取數(shù)階段的任務(wù)是:根據(jù)指令地址碼,得到操作數(shù)在主存中的地址,并從主存中讀取該操作數(shù)用于運(yùn)算;結(jié)果寫(xiě)回階段作為最后一個(gè)階段,把執(zhí)行指令階段的運(yùn)行結(jié)果數(shù)據(jù)“寫(xiě)回”到某種存儲(chǔ)形式:結(jié)果數(shù)據(jù)經(jīng)常被寫(xiě)到CPU的內(nèi)部寄存器中,以便被后續(xù)的指令快速地存取。
本文來(lái)源網(wǎng)絡(luò),版權(quán)歸原作者所有。如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系我進(jìn)行刪除。
end
一口Linux
關(guān)注,回復(fù)【1024】海量Linux資料贈(zèng)送
精彩文章合集
文章推薦
?【專(zhuān)輯】ARM?【專(zhuān)輯】粉絲問(wèn)答?【專(zhuān)輯】所有原創(chuàng)?【專(zhuān)輯】linux入門(mén)?【專(zhuān)輯】計(jì)算機(jī)網(wǎng)絡(luò)?【專(zhuān)輯】Linux驅(qū)動(dòng)?【干貨】嵌入式驅(qū)動(dòng)工程師學(xué)習(xí)路線(xiàn)?【干貨】Linux嵌入式所有知識(shí)點(diǎn)-思維導(dǎo)圖 |
|