作者:矢澤久雄[日]
譯者:李逢俊
??本文為對《程序是怎樣跑起來的》一書內(nèi)容的整理和概括达罗,部分圖片坝撑,文字摘選自書籍,如有任何侵權(quán)行為請聯(lián)系作者第一時(shí)間刪除粮揉,謝謝巡李。
對程序員來說CPU是什么
CPU的內(nèi)部結(jié)構(gòu)解析
??CPU(Central Processing Unit)職責(zé): 解釋和運(yùn)行轉(zhuǎn)換成機(jī)器語言的內(nèi)容。
程序運(yùn)行流程示例:
- 用C語言等高級語言編寫程序扶认。
- 將程序編譯后轉(zhuǎn)換成機(jī)器語言的EXE文件侨拦。
- 程序運(yùn)行時(shí),在內(nèi)存中生成EXE文件的副本辐宾。
- CPU解釋并執(zhí)行程序內(nèi)容狱从。
CPU內(nèi)部組成:寄存器(20~100個(gè)),控制器螃概,運(yùn)算器矫夯,時(shí)鐘(電流信號相互連通)。
寄存器: 暫存指令吊洼,數(shù)據(jù)等處理對象训貌。
一個(gè)CPU內(nèi)部會(huì)有20~100個(gè)寄存器。
控制器: 把內(nèi)存上的指令冒窍,數(shù)據(jù)等讀入寄存器递沪,并根據(jù)指令的結(jié)果來控制整個(gè)計(jì)算機(jī)。
時(shí)鐘: 發(fā)出CPU開始計(jì)時(shí)的時(shí)鐘信號(clock puzzle综液,頻率越高CPU運(yùn)行速度越快)款慨。
????CPU和內(nèi)存是由許多晶體管組成的電子部件,通常稱為:IC(Integrated Circuit,集成電路)谬莹。
????內(nèi)存(main memory,簡稱主存):主存通過控制芯片等與CPU相連檩奠,主要負(fù)責(zé)儲(chǔ)存指令和數(shù)據(jù)。儲(chǔ)存的內(nèi)容隨計(jì)算機(jī)的關(guān)閉而自動(dòng)清除附帽。通常使用DRAM(Dynamic Random Access Memory,動(dòng)態(tài)隨機(jī)存取儲(chǔ)存器)芯片埠戳。
CPU是寄存器的集合體
程序是把寄存器作為對象來描述的。
- 高級語言:使用類似人類的語言的語法來記敘的編程語言的總和蕉扮。如BASIC整胃,C,C++,Java,Pascal,FORTRAN等。
- 匯編語言(assembly):采用助記符(memonic)來編寫程序喳钟,每一個(gè)原本是電氣信號的機(jī)器語言指令都會(huì)有一個(gè)對應(yīng)的助記符屁使,助記符常為指令功能的單詞在岂,如mov和add分別是數(shù)據(jù)的儲(chǔ)存(move)和相加(addtion)的簡寫。
- 機(jī)器語言:CPU能夠直接解釋和執(zhí)行的語言蛮寂。(數(shù)字0和1的集合)
????通常蔽午,將匯編語言編寫的程序轉(zhuǎn)化成機(jī)器語言的過程稱為匯編;反之共郭,機(jī)器語言程序轉(zhuǎn)換成匯編語言程序的過程稱為反匯編祠丝。
????把匯編語言轉(zhuǎn)換成機(jī)器語言的程序稱為匯編器(assembler)疾呻。
????把高級語言轉(zhuǎn)換成機(jī)器語言的程序稱為編譯器(compiler)除嘹。
/* 匯編語言編寫的程序事例 */
mov eax, dword ptr [ebp-8] //把數(shù)值從內(nèi)存復(fù)制到exa
add eax, dword ptr [ebp-0Ch] //exa的數(shù)值和內(nèi)存的數(shù)值相加
mov dword ptr [ebp-4], exa //把exa的數(shù)值(上一次相加的結(jié)果)儲(chǔ)存在內(nèi)存中
????高級語言編寫的程序在編譯后轉(zhuǎn)換成機(jī)器語言,然后通過CPU內(nèi)部的寄存器來處理岸蜗。
????寄存器中儲(chǔ)存的內(nèi)容既可以是指令也可以是數(shù)據(jù)尉咕。數(shù)據(jù)分為“用于運(yùn)算的數(shù)值”和“表示內(nèi)存地址的數(shù)值”。
?????8種寄存器的主要種類和功能 如下表:
種類 | 功能 |
---|---|
累加寄存器( accumlulator register ) | 儲(chǔ)存執(zhí)行運(yùn)算后的數(shù)據(jù)和運(yùn)算后的數(shù)據(jù) |
標(biāo)志寄存器( flag register ) | 儲(chǔ)存運(yùn)算處理后的CPU狀態(tài) |
程序計(jì)數(shù)器( program counter ) | 儲(chǔ)存下一條指令所在的內(nèi)存的地址 |
基址寄存器( base register ) | 儲(chǔ)存數(shù)據(jù)內(nèi)存的起始地址 |
變址寄存器( index register ) | 儲(chǔ)存基址寄存器的相對地址 |
通用寄存器( general purpose register ) | 儲(chǔ)存任意數(shù)據(jù) |
指令寄存器( instruction register ) | 儲(chǔ)存指令璃岳。CPU內(nèi)部使用年缎,程序員無法通過程序?qū)υ摷拇嫫鬟M(jìn)行讀寫操作 |
棧寄存器( stack register ) | 儲(chǔ)存棧區(qū)域的起始地址 |
寄存器數(shù)量 | 寄存器種類 |
---|---|
僅有一個(gè) | 程序計(jì)數(shù)器,標(biāo)志寄存器铃慷,累加寄存器 |
含有多個(gè) | 基址寄存器单芜,變址寄存器,通用寄存器 |
CPU是寄存器的集合體
決定程序流程的程序計(jì)數(shù)器
????實(shí)際上一個(gè)命令和數(shù)據(jù)通常被儲(chǔ)存在多個(gè)地址上犁柜,為了方便說明把指令和數(shù)據(jù)分配到一個(gè)地址中洲鸠。
????假設(shè)地址0100
為程序開始的位置。Windows等操作系統(tǒng)把程序從硬盤復(fù)制到內(nèi)存后馋缅,會(huì)將程序計(jì)數(shù)器設(shè)定為0100
扒腕,然后程序便開始運(yùn)行。CPU每執(zhí)行一條指令萤悴,程序計(jì)數(shù)器自動(dòng)+1瘾腰。然后CPU的控制器會(huì)參照程序計(jì)數(shù)器的數(shù)值,從內(nèi)存中讀取命令并執(zhí)行覆履。
條件分支和循環(huán)機(jī)制
程序的流程分為:
- 順序執(zhí)行:執(zhí)行按照地址內(nèi)容的順序執(zhí)行指令蹋盆。執(zhí)行一條指令計(jì)數(shù)器+1。
- 條件分支:根據(jù)條件執(zhí)行任意地址的指令硝全。計(jì)數(shù)器跳轉(zhuǎn)到指定地址栖雾。
- 循環(huán):重復(fù)執(zhí)行同一地址的指令。
????條件分支和循環(huán)中使用的跳轉(zhuǎn)指令柳沙,會(huì)參照當(dāng)前執(zhí)行的運(yùn)算結(jié)果來判斷是否跳轉(zhuǎn)岩灭。無論當(dāng)前累加寄存器的運(yùn)算結(jié)果是負(fù)數(shù),零或正數(shù)赂鲤,標(biāo)志寄存器都會(huì)將其保存噪径。(也負(fù)責(zé)存放溢出和奇偶校驗(yàn)的結(jié)果)柱恤。
溢出( overflow )是指運(yùn)算結(jié)果超出寄存器的長度范圍。
-
奇偶校驗(yàn)( parity check )是指檢查運(yùn)算結(jié)果的值是偶數(shù)還是奇數(shù)找爱。
是否執(zhí)行跳轉(zhuǎn)指令由CPU在參考標(biāo)志寄存器的數(shù)值后進(jìn)行判斷梗顺。運(yùn)算結(jié)果的正負(fù)和0三種狀態(tài)由寄存器的三個(gè)字節(jié)位(0,1,2)表示。如下圖: 0位:運(yùn)算結(jié)果為正則為1车摄。
1位:運(yùn)算結(jié)果為0則為1寺谤。
2位:運(yùn)算結(jié)果為負(fù)則為1。
函數(shù)的調(diào)用機(jī)制
????單純的跳轉(zhuǎn)指令無法實(shí)現(xiàn)函數(shù)的調(diào)用吮播,而是通過把程序計(jì)數(shù)器的值設(shè)定為函數(shù)的儲(chǔ)存地址來實(shí)現(xiàn)变屁。函數(shù)的調(diào)用需要在完成函數(shù)內(nèi)部的處理后,處理流程再返回到函數(shù)的調(diào)用點(diǎn)(函數(shù)調(diào)用指令的下一地址)意狠。因此粟关,如果只是跳轉(zhuǎn)到函數(shù)的入口地址,處理流程就不知道該返回到哪了环戈。
????函數(shù)的調(diào)用使用call指令闷板,在將函數(shù)的入口地址設(shè)定到程序計(jì)數(shù)器前,call指令會(huì)把調(diào)用函數(shù)后要執(zhí)行的指令地址儲(chǔ)存在名為棧的主存內(nèi)遮晚。函數(shù)處理完后,再通過函數(shù)的出口來執(zhí)行return命令(把保存在棧中的地址設(shè)定到程序計(jì)數(shù)器中)鞠抑。
棧(stack):在程序領(lǐng)域中秒梳,棧表示不斷儲(chǔ)存各種數(shù)據(jù)的內(nèi)存區(qū)域盐茎。函數(shù)調(diào)用能夠返回調(diào)用前的地址就是因?yàn)闂探越!?/p>
通過地址和索引實(shí)現(xiàn)數(shù)組
????我們用十六進(jìn)制數(shù)將計(jì)算機(jī)內(nèi)存上00000000~FFFFFFF
的地址劃分出來。
實(shí)際查看的內(nèi)存地址 = 基址寄存器的值 + 變址寄存器的值
????例如:要訪問10000000~1000FFFF
地址時(shí)卷玉,把10000000
存入基址寄存器(基址寄存器的值被固定)蚂子,然后變址寄存器中的值可在00000000~0000FFFF
內(nèi)變化别渔,變址寄存器中的值喊儡,就相當(dāng)于高級語言程序中數(shù)組的索引功能。
????(用一個(gè)數(shù)組名來表示全體數(shù)據(jù)艾猜,通過索引來區(qū)分?jǐn)?shù)組的各個(gè)數(shù)據(jù)买喧。如,一個(gè)10元素的數(shù)組a匆赃,數(shù)據(jù)表示為a[0] ~ a[9]淤毛,其中的數(shù)字0~9就是索引)
CPU處理簡述
????下表對CPU能執(zhí)行的機(jī)器語言指令進(jìn)行分類。
類型 | 功能 |
---|---|
數(shù)據(jù)轉(zhuǎn)送指令 | 寄存器和內(nèi)存算柳,內(nèi)存和內(nèi)存低淡,寄存器和外圍設(shè)備之間的數(shù)據(jù)讀寫操作 |
運(yùn)算指令 | 用累加寄存器的執(zhí)行算術(shù)運(yùn)算,邏輯運(yùn)算,比較運(yùn)算和移位運(yùn)算 |
跳轉(zhuǎn)指令 | 實(shí)現(xiàn)條件分支蔗蹋,循環(huán)事期,強(qiáng)制跳轉(zhuǎn)等 |
call/return指令 | 函數(shù)的調(diào)用 / 返回調(diào)用前的結(jié)果 |
有關(guān)計(jì)算機(jī)二進(jìn)制對數(shù)據(jù)進(jìn)行表示及處理可參考:
明明是悟空 - 二進(jìn)制的計(jì)算(計(jì)算機(jī)為什么采用補(bǔ)碼儲(chǔ)存數(shù)據(jù))
張曉軍 - 計(jì)算機(jī)中數(shù)的表示及運(yùn)算
持續(xù)更新... ...
作者:SouthBegonia
鏈接:http://www.reibang.com/p/q81RER/
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)纸颜,非商業(yè)轉(zhuǎn)載請注明出處兽泣。