程序是怎樣跑起來(lái)的(讀書(shū)筆記)

開(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)存容量和外存容量

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舷蟀,一起剝皮案震驚了整個(gè)濱河市恤磷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌野宜,老刑警劉巖扫步,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異匈子,居然都是意外死亡河胎,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門虎敦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)游岳,“玉大人,你說(shuō)我怎么就攤上這事其徙∨咂龋” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵唾那,是天一觀的道長(zhǎng)访锻。 經(jīng)常有香客問(wèn)我,道長(zhǎng)闹获,這世上最難降的妖魔是什么期犬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮避诽,結(jié)果婚禮上龟虎,老公的妹妹穿的比我還像新娘。我一直安慰自己沙庐,他們只是感情好鲤妥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著轨功,像睡著了一般。 火紅的嫁衣襯著肌膚如雪容达。 梳的紋絲不亂的頭發(fā)上古涧,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音花盐,去河邊找鬼羡滑。 笑死菇爪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的柒昏。 我是一名探鬼主播凳宙,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼职祷!你這毒婦竟也來(lái)了氏涩?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤有梆,失蹤者是張志新(化名)和其女友劉穎是尖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體泥耀,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饺汹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痰催。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兜辞。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖夸溶,靈堂內(nèi)的尸體忽然破棺而出逸吵,到底是詐尸還是另有隱情,我是刑警寧澤蜘醋,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布胁塞,位于F島的核電站,受9級(jí)特大地震影響压语,放射性物質(zhì)發(fā)生泄漏啸罢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一胎食、第九天 我趴在偏房一處隱蔽的房頂上張望扰才。 院中可真熱鬧,春花似錦厕怜、人聲如沸衩匣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)琅捏。三九已至,卻和暖如春递雀,著一層夾襖步出監(jiān)牢的瞬間柄延,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工缀程, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搜吧,地道東北人市俊。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像滤奈,于是被迫代替她去往敵國(guó)和親摆昧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 8086匯編 本筆記是筆者觀看小甲魚(yú)老師(魚(yú)C論壇)《零基礎(chǔ)入門學(xué)習(xí)匯編語(yǔ)言》系列視頻的筆記,在此感謝他和像他一樣...
    Gibbs基閱讀 37,216評(píng)論 8 114
  • CPU是什么 程序是計(jì)算機(jī)每一步動(dòng)作的指令驹吮。程序由指令和數(shù)據(jù)組成针史,運(yùn)行的程序是存儲(chǔ)在內(nèi)存中的,構(gòu)成程序的指令和數(shù)據(jù)...
    hangbin閱讀 427評(píng)論 0 0
  • 程序是如何跑起來(lái)的 內(nèi)存和磁盤的親密關(guān)系 磁盤緩存是指:從磁盤中讀出的數(shù)據(jù)在內(nèi)存中碟狞,當(dāng)該數(shù)據(jù)再次被讀取時(shí)啄枕,不是從磁...
    Mjericho閱讀 521評(píng)論 0 1
  • 程序是怎樣跑起來(lái)的 本文主要學(xué)習(xí)自 《c程序是怎樣跑起來(lái)》一書(shū),再添加了一些自己的理解和注釋族沃,請(qǐng)各位觀者支持原版 ...
    Mjericho閱讀 576評(píng)論 0 2
  • 2011年5月底脆淹,我到目前就職的公司實(shí)習(xí)常空,兩個(gè)月后正式入職,一直呆到今天盖溺。 工作六年漓糙,六年里都經(jīng)歷了什么呢?201...
    時(shí)間的荒原閱讀 955評(píng)論 2 1