開(kāi)篇補(bǔ)充
這篇文章大概寫(xiě)于兩三個(gè)月前,但一直忘記發(fā)布文章莺奔。今天用了半小時(shí)把這篇文章大概瀏覽了下鸠珠,依然感覺(jué)能學(xué)到很多東西,因?yàn)闀r(shí)隔兩三個(gè)月有些內(nèi)容忘的差不多了锌介。但是因?yàn)橹皩?xiě)過(guò)這篇文章嗜诀,所以再次回憶這些知識(shí)點(diǎn)還是很快的。
記得三個(gè)月前找工作面試時(shí)孔祸,很多面試官都會(huì)對(duì)著我的文章來(lái)提問(wèn)隆敢。其中有一面試官,最開(kāi)始問(wèn)到我文章內(nèi)容中涉及的幾個(gè)知識(shí)融击,但是當(dāng)時(shí)沒(méi)想起來(lái)筑公。進(jìn)而面試官就帶著質(zhì)疑的態(tài)度說(shuō)"這些文章是不是你寫(xiě)的"。筆者當(dāng)時(shí)很生氣尊浪,但未表現(xiàn)出絲毫匣屡。然后回答到:"是自己寫(xiě)的,只是時(shí)間久了有些內(nèi)容記不清了"拇涤。面試官接著按筆者寫(xiě)的文章問(wèn)了不少捣作,基本回答出百分之八九十那樣。說(shuō)這件事鹅士,主要是想說(shuō)"好記性不如爛筆頭"券躁,但是卻沒(méi)多少人真正將這句話記到心中。倘若每個(gè)人都有著超凡的記憶力掉盅,那么是不是都要考清華北大∫舶荩現(xiàn)在這樣說(shuō),以后在面試過(guò)程中趾痘,若被面試官質(zhì)疑文章是不是自己原創(chuàng)慢哈,筆者可能先會(huì)說(shuō)上這些,然后讓他繼續(xù)再問(wèn)些問(wèn)題便可知曉永票。
有些知識(shí)點(diǎn)隨著時(shí)間久遠(yuǎn)卵贱,很可能會(huì)記不清滥沫,但是當(dāng)我翻看自己的博客文章,會(huì)以最快的速度想起那些知識(shí)點(diǎn)键俱,畢竟文章的每一個(gè)字都是出自我自己的手兰绣,整個(gè)寫(xiě)作都是出自自己以往的思路。
前言
對(duì)于很多半路出家轉(zhuǎn)行到 IT 行業(yè)的技術(shù)小白而言编振,說(shuō)自己是程序員缀辩,但是請(qǐng)問(wèn)問(wèn)自己是否可以講清楚什么是編程。敲了那么多代碼党觅,又能否解釋清楚程序到底是怎樣跑起來(lái)的(包括軟件到硬件整個(gè)執(zhí)行流程)雌澄。
是不是有點(diǎn)困難!沒(méi)關(guān)系杯瞻,筆者向你推薦一本很基礎(chǔ)的書(shū) 《程序是怎樣跑起來(lái)的》镐牺。筆者用了大概兩天多的時(shí)間簡(jiǎn)單過(guò)了下這本書(shū),現(xiàn)在對(duì)程序的整個(gè)運(yùn)行流程有了簡(jiǎn)單的認(rèn)識(shí)魁莉,包括CPU睬涧、虛擬內(nèi)存、物理內(nèi)存旗唁、操作系統(tǒng)畦浓、硬件和驅(qū)動(dòng)等相關(guān)。整本書(shū)的內(nèi)容通俗簡(jiǎn)單易懂检疫,雖說(shuō)深度不是很深讶请,但很適合對(duì)計(jì)算機(jī)硬件一竅不懂的小白。如果有需要筆者這有電子版的書(shū)屎媳。
還是保持以前的習(xí)慣夺溢,學(xué)習(xí)后就要記錄點(diǎn)內(nèi)容。
一烛谊、CPU是什么
1.1 程序運(yùn)行流程
- a. 程序員編寫(xiě)高級(jí)語(yǔ)言风响。
int a; a = 1+2; printf("%d",a);
- b、將程序編譯后轉(zhuǎn)換成機(jī)器語(yǔ)言的 EXE 文件丹禀。
010000101001010101010010101010100101010101010010101
- c状勤、程序運(yùn)行時(shí),在內(nèi)存中生成 EXE 文件的副本双泪。
- d持搜、CPU 解釋并執(zhí)行程序。
1.2 CPU結(jié)構(gòu)
CPU 和內(nèi)存都是有許多晶體組成的電子部件焙矛,通常稱之為 IC(集成電路)朵诫。從功能方面來(lái)說(shuō),CPU 主要由四部分構(gòu)成薄扁,其中控制器和運(yùn)算器最為核心剪返。
- 寄存器:用來(lái)暫存指令,數(shù)據(jù)等處理對(duì)象邓梅,可以將它看成內(nèi)存的一種脱盲,CPU 內(nèi)部會(huì)有 20-100 個(gè)寄存器。
- 控制器:負(fù)責(zé)把內(nèi)存上的指令日缨,數(shù)據(jù)讀入寄存器钱反,并根據(jù)指令的執(zhí)行結(jié)果來(lái)控制整個(gè)計(jì)算機(jī)。
- 運(yùn)算器:負(fù)責(zé)運(yùn)算從內(nèi)存讀入寄存器的數(shù)據(jù)匣距。
- 時(shí)鐘:負(fù)責(zé)發(fā)出 CPU 開(kāi)始計(jì)時(shí)的時(shí)鐘信號(hào)面哥。
程序啟動(dòng)后,根據(jù)時(shí)鐘
信號(hào)毅待,控制器
從內(nèi)存中讀取指令和數(shù)據(jù)尚卫,通過(guò)這些指令加以解釋和運(yùn)行,運(yùn)算器
會(huì)對(duì)數(shù)據(jù)進(jìn)行運(yùn)算尸红,控制器
根據(jù)該運(yùn)算結(jié)果來(lái)控制計(jì)算機(jī)(所謂的控制就是指數(shù)據(jù)運(yùn)算以外的處理吱涉,如:數(shù)據(jù)輸入和輸出事件的控制、鍵盤外里、顯示器等的輸入輸出怎爵。
這里順便說(shuō)一下內(nèi)存的概念: 通常說(shuō)的內(nèi)存是指計(jì)算機(jī)的主存儲(chǔ)器,簡(jiǎn)稱 主存盅蝗,主存通過(guò)控制芯片等與 CPU 相連鳖链,主要負(fù)責(zé)存儲(chǔ)指令和數(shù)據(jù),主存由可讀寫(xiě)的元素構(gòu)成墩莫,每個(gè)字節(jié)(1個(gè)字節(jié) =8 位)都帶有一個(gè)地址編號(hào)芙委,CPU 可以通過(guò)改地址讀取主存中的指令和數(shù)據(jù),當(dāng)然也可以寫(xiě)入數(shù)據(jù)贼穆,但是需要注意的是题山,主存中存儲(chǔ)的指令和數(shù)據(jù)會(huì)隨著計(jì)算機(jī)的關(guān)機(jī)而自動(dòng)清除。
1.3 CPU結(jié)構(gòu)中的寄存器
CPU 是寄存器的集合體故痊。不同類型的 CPU 內(nèi)部寄存器的種類和數(shù)量都是不同的顶瞳。不過(guò),一般情況下可將寄存器大致分為八類:
- 累加寄存器: 存儲(chǔ)執(zhí)行運(yùn)算的數(shù)據(jù)和運(yùn)算后的數(shù)據(jù) (1個(gè))
- 標(biāo)志寄存器: 存儲(chǔ)運(yùn)算處理后的 CPU 狀態(tài) (1個(gè))
- 程序計(jì)數(shù)器: 存儲(chǔ)下一條指令所在的內(nèi)存的地址 (1個(gè))
- 指令寄存器: 存儲(chǔ)指令愕秫, CPU 內(nèi)部使用慨菱,程序員無(wú)法通過(guò)程序?qū)υ摷拇嫫鬟M(jìn)行讀寫(xiě)操作。(1個(gè))
- 棧寄存器: 存儲(chǔ)棧區(qū)域的起始地址 (1個(gè))
- 基址寄存器: 存儲(chǔ)數(shù)據(jù)內(nèi)存的起始地址
- 變址寄存器: 存儲(chǔ)基址寄存器的相對(duì)地址
- 通用寄存器: 存儲(chǔ)任意數(shù)據(jù)
程序計(jì)數(shù)器戴甩、累加寄存器符喝、標(biāo)志寄存器、指令寄存器和棧寄存器只有一個(gè)甜孤,而像基址寄存器
协饲、變址寄存器
畏腕、通用寄存器
通常都有多個(gè)。
1.4 程序計(jì)數(shù)器決定程序流程
1.4.1 順序執(zhí)行
比如實(shí)現(xiàn) 123 和 456 兩個(gè)數(shù)值相加茉稠,并顯示到屏幕上描馅。實(shí)際上,一個(gè)命令和數(shù)據(jù)通常被存儲(chǔ)在多個(gè)地址山而线,但是這里為了便于說(shuō)明旬渠,就把指令和數(shù)據(jù)假設(shè)分配到一個(gè)地址上刹淌。
地址 0100 是程序運(yùn)行的開(kāi)始位置济似。操作系統(tǒng)首先把程序復(fù)制到內(nèi)存中衍腥,然后程序計(jì)數(shù)器(CPU寄存器的一種)設(shè)定為0100,便開(kāi)始運(yùn)行誓竿。CPU 每執(zhí)行一個(gè)指令磅网,程序計(jì)數(shù)器就加 1 。
1.4.2 條件分支和循環(huán)執(zhí)行
條件分支根據(jù)條件執(zhí)行任意地址的指令烤黍。循環(huán)則會(huì)重復(fù)執(zhí)行同一地址的指令知市。
CPU 在進(jìn)行運(yùn)算時(shí),
標(biāo)志寄存器
的數(shù)值會(huì)根據(jù)運(yùn)算結(jié)果自動(dòng)設(shè)定速蕊,至于是否執(zhí)行跳轉(zhuǎn)指令嫂丙,則由 CPU 參考標(biāo)志寄存器的數(shù)值進(jìn)行判斷。
1.4.3 函數(shù)調(diào)用機(jī)制
如果只有順序规哲、分支跟啤、循環(huán)順序執(zhí)行函數(shù),當(dāng)執(zhí)行到
c = MyFunc(a,b)
并進(jìn)入該函數(shù)唉锌,當(dāng)該函數(shù)執(zhí)行到完隅肥,如何確定下一個(gè)地址?關(guān)于這個(gè)問(wèn)題袄简,機(jī)器語(yǔ)言的 call
指令和 return
指令能夠解決當(dāng)函數(shù)調(diào)用后執(zhí)行后返回的問(wèn)題腥放。函數(shù)調(diào)用使用的是 call 指令 而不是跳轉(zhuǎn)指令,在將函數(shù)的入口地址設(shè)定到程序計(jì)數(shù)器之前绿语, call 指令會(huì)把調(diào)用函數(shù)后要執(zhí)行的指令地址存儲(chǔ)在名為棧的主存中秃症,函數(shù)處理完畢后,再通過(guò)函數(shù)的出口來(lái)執(zhí)行 return 命令吕粹, return 命令的功能是把保存在棧中的地址設(shè)定到程序計(jì)數(shù)器中种柑。
二、關(guān)于二進(jìn)制
2.1 用二進(jìn)制表示計(jì)算機(jī)信息的原因
計(jì)算機(jī)內(nèi)部是由 IC(集成電路) 這種電子部件構(gòu)成的匹耕。IC有集中不同的醒轉(zhuǎn)聚请,有的像一條黑色蜈蚣,在其兩側(cè)有很多引腳稳其。IC 的所有引腳驶赏,只有直流電壓0V或5V兩個(gè)狀態(tài)炸卑,也就是說(shuō)IC的一個(gè)引腳只能表示兩個(gè)狀態(tài)(0或1)。IC 的這個(gè)特性決定了計(jì)算機(jī)的信息數(shù)據(jù)只能用二進(jìn)制來(lái)處理母市。雖然二進(jìn)制并不是專門為IC而設(shè)計(jì)的矾兜,但是和IC的特性非常吻合。計(jì)算機(jī)最小的處理單位是---位患久,每個(gè)引腳相當(dāng)于二進(jìn)制中的一位,1 字節(jié) = 8位浑槽。
2.2 原碼蒋失、反碼、補(bǔ)碼
- 正數(shù): 反碼 = 原碼 = 補(bǔ)碼
- 負(fù)數(shù):
反碼 = 其原碼除符號(hào)之外的各位求反
補(bǔ)碼 = 反碼 + 1
正數(shù)的原碼桐玻、反碼篙挽、補(bǔ)碼
原碼: 01011
反碼: 01011
補(bǔ)碼: 01011
負(fù)數(shù)的原碼、反碼镊靴、補(bǔ)碼
原碼: 11011
反碼: 10100
補(bǔ)碼: 10101
另外铣卡,有一點(diǎn)非常重要的,計(jì)算機(jī)中偏竟,數(shù)據(jù)一律通過(guò)補(bǔ)碼來(lái)存儲(chǔ)煮落。
2.3 乘除運(yùn)算與移位運(yùn)算
00100111 左移兩位的結(jié)果是 10011100,用十進(jìn)制表示的話踊谋,從39變?yōu)?56蝉仇,是之前的 4 倍。類比的話殖蚕,十進(jìn)制左移會(huì)變?yōu)樵瓉?lái)的10倍轿衔、100倍.....,二進(jìn)制左移會(huì)變?yōu)樵瓉?lái)的2倍睦疫、4倍害驹、8倍.....反之,右移會(huì)變?yōu)樵瓉?lái)的1/2蛤育、1/4.......如此就能解釋為什么移位運(yùn)算可以代替乘除法宛官。
2.4 計(jì)算機(jī)進(jìn)行小數(shù)運(yùn)算原因
2.4.1 如何用二進(jìn)制表示小數(shù)
先看看小數(shù)如何通過(guò)二進(jìn)制小數(shù)表示。實(shí)際上適合表示整數(shù)的方式類似缨伊。具體請(qǐng)參照下圖摘刑。
2.4.2 計(jì)算機(jī)運(yùn)算出錯(cuò)的原因
計(jì)算機(jī)之所以會(huì)出現(xiàn)運(yùn)算錯(cuò)誤的原因是因?yàn)橐恍┬?shù)無(wú)法轉(zhuǎn)換二進(jìn)制數(shù),例如 0.1 刻坊,就無(wú)法用二進(jìn)制數(shù)正確表示枷恕,小數(shù)點(diǎn)后面即使有幾百位也無(wú)法表示。按照下表的規(guī)律可知道谭胚,十進(jìn)制0.1 轉(zhuǎn)換成二進(jìn)制后徐块,會(huì)變成0.00011001100......(1100)會(huì)這樣一直循環(huán)下去未玻。這種情況就像1/3無(wú)法用十進(jìn)制來(lái)表示一樣。
2.4.3 如何避免計(jì)算機(jī)出錯(cuò)
把小數(shù)轉(zhuǎn)成整數(shù)計(jì)算胡控。計(jì)算機(jī)在進(jìn)行小數(shù)計(jì)算時(shí)可能會(huì)出錯(cuò)扳剿,但是在計(jì)算整數(shù)的時(shí)候,只要不超過(guò)可處理數(shù)值的范圍一定不會(huì)出現(xiàn)問(wèn)題昼激。
三庇绽、內(nèi)存
通常說(shuō)的內(nèi)存是指計(jì)算機(jī)的主存儲(chǔ)器,簡(jiǎn)稱 主存橙困,主存通過(guò)控制芯片等與 CPU 相連瞧掺,主要負(fù)責(zé)存儲(chǔ)指令和數(shù)據(jù),主存由可讀寫(xiě)的元素構(gòu)成凡傅,每個(gè)字節(jié)(1個(gè)字節(jié) =8 位)都帶有一個(gè)地址編號(hào)辟狈,CPU 可以通過(guò)改地址讀取主存中的指令和數(shù)據(jù),當(dāng)然也可以寫(xiě)入數(shù)據(jù)夏跷,但是需要注意的是哼转,主存中存儲(chǔ)的指令和數(shù)據(jù)會(huì)隨著計(jì)算機(jī)的關(guān)機(jī)而自動(dòng)清除。
3.1 內(nèi)存的物理機(jī)制
內(nèi)存實(shí)際上是一種名為內(nèi)存 IC 的電子元件槽华,內(nèi)存 IC 中有電源壹蔓、地址信號(hào)、數(shù)據(jù)信號(hào)硼莽、控制信號(hào)等用于輸入輸出的大量引腳(IC 的引腳)庶溶,通過(guò)為其制定地址,來(lái)進(jìn)行數(shù)據(jù)的讀寫(xiě)懂鸵。
3.2 內(nèi)存的邏輯模型
char a;
short b;
long c;
a = 123;
b = 123;
c = 123;
a 表示一個(gè)字節(jié)長(zhǎng)度的 char偏螺,b 表示 2 個(gè)字節(jié)的short,c 表示 4 個(gè)字節(jié)的 long匆光。下圖的地址從上往下變大套像,但實(shí)際也會(huì)有相反的情況。
四终息、磁盤和內(nèi)存的關(guān)系
4.1 不讀入內(nèi)存就無(wú)法運(yùn)行
磁盤中存儲(chǔ)的程序夺巩,必須要加載到內(nèi)存中才能運(yùn)行,在磁盤中保存的原始程序是無(wú)法直接運(yùn)行的周崭,這是因?yàn)榱?fù)責(zé)解析。
4.2 磁盤緩存加快了磁盤訪問(wèn)速度
磁盤緩存
是從磁盤中讀取的數(shù)據(jù)存儲(chǔ)在內(nèi)存空間续镇。如此美澳,當(dāng)接下來(lái)需要讀取同一數(shù)據(jù),就可以直接從內(nèi)存中讀取,而不用再次通過(guò)磁盤讀取制跟。磁盤緩存
這種方式可以加快磁盤數(shù)據(jù)的訪問(wèn)速度舅桩。
4.3 虛擬內(nèi)存
虛擬內(nèi)存
是指把磁盤的一部分作為假想的內(nèi)存來(lái)使用。虛擬內(nèi)存實(shí)際是假想的內(nèi)存(實(shí)際上是磁盤)雨膨。借助虛擬內(nèi)存
擂涛,在內(nèi)存不足時(shí)也可以運(yùn)行程序。例如在只剩下 5MB 內(nèi)存空間的情況下也能運(yùn)行 10MB 大小的程序聊记,由于 CPU 只能執(zhí)行加載到內(nèi)存中的程序撒妈,虛擬內(nèi)存
雖說(shuō)是把磁盤作為內(nèi)存的一部分來(lái)使用,但實(shí)際上正在運(yùn)行的程序部分排监,在這個(gè)時(shí)間點(diǎn)上必須存在在內(nèi)存中踩身,也就是說(shuō),為了實(shí)現(xiàn)虛擬內(nèi)存社露,就必須把實(shí)際內(nèi)存
的內(nèi)容和磁盤上的虛擬內(nèi)存
的內(nèi)容進(jìn)行部分置換(swap),并同時(shí)運(yùn)行程序。通常情況下琼娘,PC端都有swap機(jī)制峭弟,所以一般情況下,PC端的應(yīng)用不會(huì)被殺死脱拼。但是移動(dòng)端卻不同瞒瘸,由于沒(méi)有swap機(jī)制,為了運(yùn)行更多的程序熄浓,只能選擇殺死之前的程序情臭。
為了實(shí)現(xiàn)虛擬內(nèi)存功能, Windows 在磁盤上提供了虛擬內(nèi)存用的文件(page file, 頁(yè)文件)赌蔑,該文件由 Windows 自動(dòng)做成和管理俯在,文件的大小也就是虛擬內(nèi)存的大小,通常是實(shí)際內(nèi)存的相同程度至兩倍程度娃惯。
4.4 系統(tǒng)節(jié)約內(nèi)存的方法
通過(guò)DLL(Dynamic Link Library)文件跷乐,在程序運(yùn)行時(shí)動(dòng)態(tài)加載Library。多個(gè)應(yīng)用可以共用一個(gè)DLL文件趾浅,達(dá)到節(jié)約內(nèi)存的效果愕提。
4.5 磁盤的物理結(jié)構(gòu)
磁盤是通過(guò)把其物理表面劃分成多個(gè)空間來(lái)使用的,劃分的方式有扇區(qū)方式和可變長(zhǎng)方式皿哨,前者指將磁盤劃分為固定長(zhǎng)度的空間浅侨,后者則是把磁盤劃分為長(zhǎng)度可變的空間,扇區(qū)方式中证膨,把磁盤的表面劃分成若干個(gè)同心圓空間的就是磁道如输,把磁道按照固定大小(能存儲(chǔ)的數(shù)據(jù)長(zhǎng)度相同)劃分而成的空間就是扇面。
扇區(qū)是磁盤的最小讀寫(xiě)單位,一般一個(gè)扇區(qū)是512字節(jié)挨决。磁盤讀寫(xiě)的單位是扇區(qū)整數(shù)倍的
簇
(1簇可以是1扇區(qū)既512字節(jié)请祖、也可以是2扇區(qū)既1KB.......以此類推)。通常磁盤的容量越大脖祈,簇的容量也越大肆捕。
- 不同的文件文件不能存在同一個(gè)簇中,否則會(huì)導(dǎo)致乙方的文件不能被刪除盖高。
- 不管多么小的文件慎陵,至少會(huì)占1簇的空間。其他文件所占的空間都是簇的整數(shù)倍喻奥。
五席纽、文件壓縮
關(guān)于這個(gè)就不結(jié)合這本書(shū)的內(nèi)容來(lái)說(shuō)了,之前寫(xiě)過(guò)一篇相關(guān)文章撞蚕,可做簡(jiǎn)單參考润梯。
六、程序的運(yùn)行環(huán)境
程序的運(yùn)行環(huán)境 = 操作系統(tǒng) + 硬件
七甥厦、從源文件到可執(zhí)行文件
關(guān)于這個(gè)就不結(jié)合這本書(shū)的內(nèi)容來(lái)說(shuō)了纺铭,之前寫(xiě)過(guò)一篇相關(guān)文章,可做簡(jiǎn)單參考刀疙。注意文中提到的編譯的前后端問(wèn)題舶赔。
八、操作系統(tǒng)和應(yīng)用的關(guān)系
8.1 操作系統(tǒng)是多個(gè)應(yīng)用的集合
在計(jì)算機(jī)不存在操作系統(tǒng)一說(shuō)的年代谦秧,開(kāi)發(fā)人員用機(jī)器語(yǔ)言編寫(xiě)程序竟纳,然后使用硬件開(kāi)發(fā)將程序輸入,這一過(guò)程非常麻煩疚鲤。于是锥累,有人開(kāi)發(fā)出僅具有加載和運(yùn)行功能的監(jiān)控程序
,這就是操作系統(tǒng)的原型。通過(guò)實(shí)現(xiàn)啟動(dòng)監(jiān)控程序石咬,程序員就可以根據(jù)需要將各種程序加載到內(nèi)存中運(yùn)行揩悄。
隨著后期的發(fā)展,人們意思到很多程序都有共通的部分鬼悠。如通過(guò)鍵盤輸入文字删性、顯示器輸出文字等。如果每個(gè)程序都額外加上這些相同的處理焕窝,就太浪費(fèi)時(shí)間了蹬挺。所以,后來(lái)就將這些基本的輸入輸出等程序加到監(jiān)控程序中它掂。初期的操作系統(tǒng)就這樣誕生了巴帮。
8.2 要意識(shí)到操作系統(tǒng)的存在
之所以說(shuō)要意識(shí)到操作系統(tǒng)的存在溯泣,是因?yàn)槌绦騿T在開(kāi)發(fā)應(yīng)用,而不是在開(kāi)發(fā)硬件榕茧。因?yàn)椴僮飨到y(tǒng)的存在垃沦,程序員無(wú)需考慮硬件問(wèn)題,哪怕是對(duì)硬件不懂的人用押,也同樣能開(kāi)發(fā)出有模有樣的應(yīng)用肢簿。因?yàn)閼?yīng)用不是直接控制硬件,而是通過(guò)操作系統(tǒng)來(lái)間接控制硬件蜻拨。
九池充、關(guān)于匯編
9.1 匯編語(yǔ)言和本地代碼一一對(duì)應(yīng)
高級(jí)語(yǔ)言經(jīng)過(guò)編譯器被翻譯成匯編語(yǔ)言,這個(gè)過(guò)程是一條高級(jí)語(yǔ)言可能被翻譯成多條匯編語(yǔ)言缎讼。而匯編語(yǔ)言經(jīng)過(guò)匯編器被翻譯成機(jī)器語(yǔ)言收夸,這個(gè)過(guò)程是1條匯編語(yǔ)言翻譯成1條二進(jìn)制的機(jī)器語(yǔ)言。計(jì)算機(jī) CPU 能直接解釋運(yùn)行的只有本地代碼程序血崭,用 C 語(yǔ)言等編寫(xiě)的代碼卧惜,需要通過(guò)各自的編譯器編譯后,轉(zhuǎn)換成本地代碼夹纫。
9.2 匯編語(yǔ)言的語(yǔ)法是‘操作碼+操作數(shù)’
在匯編語(yǔ)言中序苏,一行表示對(duì) CPU 的一個(gè)指令。匯編語(yǔ)言指令的語(yǔ)法結(jié)構(gòu)是操作碼+操作數(shù)捷凄。操作碼表示的是指令動(dòng)作,操作數(shù)表示的是指令對(duì)象围来。操作碼和操作數(shù)羅列在一起的語(yǔ)法跺涤,就是一個(gè)英文的指令文本。操作碼是動(dòng)詞监透,操作數(shù)相當(dāng)于賓語(yǔ)桶错。如:Give me money, Give 相當(dāng)于操作碼,me和money就是操作數(shù)胀蛮。匯編語(yǔ)言中如果存在多個(gè)操作數(shù)院刁,就用逗號(hào)分割開(kāi),就像 Give me, money 這樣粪狼。
9.3 對(duì)棧進(jìn)行 push 和 pop
程序運(yùn)行時(shí)退腥,會(huì)在內(nèi)存上申請(qǐng)分配一個(gè)稱為棧的數(shù)據(jù)空間,數(shù)據(jù)在存儲(chǔ)時(shí)是從內(nèi)存的下層(大號(hào)地址)逐漸往上層累加的再榄,讀出時(shí)是按照從上往下的順序進(jìn)行的狡刘。棧是存儲(chǔ)臨時(shí)數(shù)據(jù)的區(qū)域,32位 x86 系列的 CPU 中困鸥,進(jìn)行一次 push 或 pop操作嗅蔬,即可處理32位(4字節(jié))的數(shù)據(jù)。
push 和 pop 指令中只有一個(gè)操作數(shù),該操作數(shù)表示的是 push 的是什么或 pop 的是什么澜术,而不需要指定對(duì)哪一個(gè)地址編號(hào)的內(nèi)存進(jìn)行 push 和 pop 艺蝴。這是因?yàn)椋瑢?duì)棧進(jìn)行讀寫(xiě)的內(nèi)存地址編號(hào)是由 esp 寄存器(棧指針)進(jìn)行管理的鸟废。push 指令和 pop指令運(yùn)行后猜敢,esp 寄存器的值會(huì)自動(dòng)進(jìn)行更新,push指令減4侮攀,pop命令是加4锣枝,因而程序員就沒(méi)有必要指定內(nèi)存地址了。
9.4 函數(shù)調(diào)用機(jī)制
匯編語(yǔ)言中兰英,函數(shù)名表示的是函數(shù)所在的內(nèi)存地址撇叁,當(dāng) call 命令調(diào)用的函數(shù)運(yùn)行結(jié)束后,程序流程會(huì)返回編號(hào) (6) 的這一行畦贸。 call 指令運(yùn)行開(kāi)始后陨闹, call 指令的內(nèi)部執(zhí)行方法的內(nèi)存地址 (6 的這一行) 會(huì)自動(dòng) push 入棧,該值會(huì)在 AddNum 函數(shù)處理完成后薄坏,最后通過(guò) ret 指令 pop 出棧趋厉,然后流程回到編號(hào)為 6 這一行。
9.5 函數(shù)內(nèi)部的處理
函數(shù)是的參數(shù)是通過(guò)棧來(lái)傳遞的胶坠,返回值是通過(guò)寄存器來(lái)返回的君账。
ebp 寄存器的值在(1)中入棧,在(5)中出棧沈善,主要是為了把函數(shù)中用到的 ebp 寄存器的內(nèi)容乡数,恢復(fù)到函數(shù)調(diào)用之前的狀態(tài)。在進(jìn)入函數(shù)處理之前闻牡,無(wú)法確定 ebp 寄存器用到了什么地方净赴,但由于函數(shù)內(nèi)部也會(huì)用到 ebp 寄存器,所以就暫時(shí)將改值保存起來(lái)罩润。
(2)中把負(fù)責(zé)管理地址的 esp 寄存器的值賦到了 ebp 寄存器中玖翅,這是因?yàn)?mov 指令中方括號(hào)的參數(shù),是不允許指令 esp 寄存器的割以。因此這里就采用不直接通過(guò) esp 金度,而是用 ebp 寄存器來(lái)讀寫(xiě)棧內(nèi)容的方法。
(6)中 ret 指令運(yùn)行后严沥,函數(shù)返回目的地的內(nèi)存地址會(huì)自動(dòng)出棧审姓。跳出函數(shù)內(nèi)部。
9.6 全局變量和臨時(shí)變量
編譯后的程序祝峻,會(huì)被歸類到名為段定義的組魔吐,初始化的全局變量扎筒,會(huì)被定義到名為 _DATA 的段定義中,沒(méi)有初始化的全局變量會(huì)被匯總到 _BSS 的段定義中酬姆,指令會(huì)被匯總到名為 _TEXT 的段定義中嗜桌。
局部變量臨時(shí)保存在寄存器和棧中,所以局部變量只能在定義該函數(shù)的內(nèi)部進(jìn)行參閱辞色。函數(shù)內(nèi)部利用棧骨宠,在函數(shù)處理完畢后會(huì)恢復(fù)到初始狀態(tài),因此局部變量的值也就被銷毀了相满。而寄存器也可能會(huì)被用于其他目的层亿,因此,局部變量只是在函數(shù)處理運(yùn)行期間臨時(shí)存儲(chǔ)在寄存器和棧上立美。
十匿又、硬件控制方法
10.1 應(yīng)用和硬件無(wú)關(guān)
應(yīng)用不是直接控制硬件,而是通過(guò)操作系統(tǒng)來(lái)間接控制硬件建蹄。所以說(shuō)應(yīng)用和硬件無(wú)關(guān)碌更。
10.2 支持硬件輸入和輸出的IN和OUT指令
- IN指令通過(guò)端口號(hào)的端口輸入數(shù)據(jù),并將其存儲(chǔ)在 CPU 內(nèi)部的寄存器中痛单。
- OUT 指令則是把 CPU 寄存器中的存儲(chǔ)的數(shù)據(jù),輸出到指定端口號(hào)的端口劲腿。
什么是端口旭绒?端口號(hào)?I/O控制器焦人?
計(jì)算機(jī)主機(jī)快压,附帶了顯示器、鍵盤等外圍設(shè)備的連接器
垃瞧。連接器
內(nèi)部都有用來(lái)交換計(jì)算機(jī)同外圍設(shè)置之間電流特性的I/O控制器
。I/O控制器
之所以存在坪郭,是為了解決因電壓不同个从,數(shù)字信號(hào)和模擬信號(hào)的電流特性也不同,計(jì)算機(jī)主機(jī)和外圍設(shè)備無(wú)法直接相連的問(wèn)題歪沃。 而I/O控制器
中有用于臨時(shí)保存輸入輸出數(shù)據(jù)的內(nèi)存嗦锐,該內(nèi)存就是端口。I/O控制器
內(nèi)部的內(nèi)存也稱為寄存器沪曙,但是該寄存器不同于 CPU 內(nèi)部的寄存器奕污。CPU 內(nèi)部的寄存器主要是用來(lái)計(jì)算,而這里的寄存器主要是用來(lái)臨時(shí)存儲(chǔ)數(shù)據(jù)液走。 一個(gè)I/O控制器
可以控制一個(gè)也可以控制多個(gè)外圍設(shè)備碳默,各端口之間通過(guò)端口號(hào)區(qū)分贾陷,端口號(hào)也稱為I/O地址
。
10.3文字和圖片顯示機(jī)制
簡(jiǎn)單一句話概括:顯示器中顯示的信息一直存儲(chǔ)在某內(nèi)存中嘱根,該內(nèi)存稱為VRAM(Video RAM)髓废。只要往VRAM中寫(xiě)入數(shù)據(jù),數(shù)據(jù)就會(huì)顯示出來(lái)该抒。
在MS_DOS時(shí)代慌洪,VRAM是主內(nèi)存的一部分。不過(guò)當(dāng)時(shí)因?yàn)閂RAM內(nèi)存空間太小凑保,最多只能有16中顏色「缘現(xiàn)代計(jì)算機(jī),顯卡等專用硬件中一般都配置與主內(nèi)存獨(dú)立的VRAM和GPU欧引。
額外擴(kuò)充
計(jì)算機(jī)系統(tǒng)性能指標(biāo)
基本字長(zhǎng)
即一次數(shù)據(jù)操作的基本位數(shù)频伤,通常是4位、8位维咸、16位剂买、64位等,它會(huì)影響到計(jì)算的精度癌蓖、指令的功能瞬哼。位數(shù)越大,計(jì)算精度越高租副,指令越豐富坐慰,性能越好。如32位和64位操作系統(tǒng)相比用僧。運(yùn)算速度不同:64位CPU GPRs(General-Purpose Registers结胀,通用寄存器)的數(shù)據(jù)寬度為64位,64位指令集可以運(yùn)行64位數(shù)據(jù)指令责循,也就是說(shuō)處理器一次可提取64位數(shù)據(jù)(只要兩個(gè)指令糟港,一次提取8個(gè)字節(jié)的數(shù)據(jù)),比32位(需要四個(gè)指令,一次提取4個(gè)字節(jié)的數(shù)據(jù))提高了一倍院仿,理論上性能會(huì)相應(yīng)提升1倍秸抚;尋址能力不同:64位處理器的優(yōu)勢(shì)還體現(xiàn)在系統(tǒng)對(duì)內(nèi)存的控制上。由于地址使用的是特殊的整數(shù)歹垫,因此一個(gè)ALU(算術(shù)邏輯運(yùn)算器)和寄存器可以處理更大的整數(shù)剥汤,也就是更大的地址。比如排惨,Windows Vista x64 Edition支持多達(dá)128 GB的內(nèi)存和多達(dá)16 TB的虛擬內(nèi)存吭敢,而32位CPU和操作系統(tǒng)最大只可支持4G內(nèi)存。CPU的性能指標(biāo)
cpu的主頻=外頻*倍頻系數(shù)暮芭;
IPS表示每秒執(zhí)行指令數(shù)鹿驼;
FLOPS表示每秒執(zhí)行浮點(diǎn)運(yùn)算的次數(shù)欲低;天河2號(hào)實(shí)測(cè)速度為33.86PFLOPS。
CPU的功耗(動(dòng)態(tài)功耗和靜態(tài)功耗)蠢沿,動(dòng)態(tài)功耗是指實(shí)際運(yùn)行計(jì)算產(chǎn)生的功耗伸头,靜態(tài)功耗是指半導(dǎo)體材料在電流流動(dòng)中的泄露和揮發(fā);存儲(chǔ)器的容量
內(nèi)存容量和外存容量