csapp第一章 计算机系统漫游 学习和理解
?計(jì)算機(jī)系統(tǒng)是由硬件和系統(tǒng)軟件組成的。
系統(tǒng)的具體實(shí)現(xiàn)在變,但系統(tǒng)內(nèi)在的概念沒(méi)有變。
所有的系統(tǒng)都有相似的硬件,相似的軟件組件,它們執(zhí)行著相似的功能。
這些組件是如何工作的?這些組件是如何影響程序的正確性和性能的?本書(shū)予以解答。
K&R的hello程序要完成運(yùn)行,系統(tǒng)的每個(gè)組成部分都需要協(xié)調(diào)工作。本書(shū)就是告訴你在系統(tǒng)上運(yùn)行hello程序時(shí),系統(tǒng)發(fā)生了什么以及為什么會(huì)這樣。
1.1 信息就是位+上下文
圖1-2真的是hello.c的ASCII碼表示,除了可見(jiàn)的字符外,不可見(jiàn)的是sp和\n,從第一個(gè)到最后一個(gè)完整的表示出來(lái)。這就是文本文件。
“\n”是在每一行的結(jié)尾處,或者說(shuō)有“\n"才有一行的結(jié)束,其表現(xiàn)就是光標(biāo)到了下一行,另起一行。
這里說(shuō)ASCII字符構(gòu)成的文件稱為文本文件,所有其他文件都是二進(jìn)制文件,我想有點(diǎn)不對(duì),應(yīng)該是所有由編碼字符構(gòu)成了文件是文本文件,其他是二進(jìn)制文件。編碼字符不止ASCII,還有UTF-8等等,ASCII不可以表示中文。
系統(tǒng)的所有信息都是一串位,區(qū)分這些位表示什么信息的方法,唯一方法,是讀到這些位時(shí)候的上下文。
這個(gè)上下文既然是從位的角度講的,那么至少也是在匯編語(yǔ)言級(jí)別去解釋,比如mov,是movb還是movw,這種就應(yīng)該算是上下文,更底層的機(jī)器語(yǔ)言就看不懂了。c語(yǔ)言也不是,c的表達(dá)方式就已經(jīng)在文本級(jí)別了,與位其實(shí)有一定的差距了。(這句話的理解也不知道對(duì)不對(duì),暫且不管)
c語(yǔ)言是系統(tǒng)級(jí)編程的首選,同時(shí)也非常適用于應(yīng)用級(jí)程序的編寫(xiě)。c++和java是應(yīng)用級(jí)程序的新的程序設(shè)計(jì)語(yǔ)言。
1.2 程序被其他程序翻譯成不同的格式
可執(zhí)行目標(biāo)文件是二進(jìn)制文件,是按照一種格式打包起來(lái)的,這個(gè)格式稱為可執(zhí)行目標(biāo)程序,打包的對(duì)象是從每條c語(yǔ)句轉(zhuǎn)化出來(lái)的低級(jí)機(jī)器語(yǔ)言指令。
編譯器驅(qū)動(dòng)程序完成從源文件到可執(zhí)行目標(biāo)文件的轉(zhuǎn)化。這里有驅(qū)動(dòng)兩個(gè)字。
轉(zhuǎn)化的過(guò)程有4個(gè)階段,分別用到預(yù)處理器,編譯器,匯編器,鏈接器。
- 預(yù)處理器處理的是以字符#開(kāi)頭的命令,也就是說(shuō)#開(kāi)頭的就是預(yù)處理命令,會(huì)經(jīng)過(guò)預(yù)處理器處理。
- 編譯器為不同的高級(jí)語(yǔ)言的不同的編譯器提供了通用的輸出語(yǔ)言—匯編語(yǔ)言。
- 匯編器也會(huì)打包,按照可重定位目標(biāo)程序的格式來(lái)打包。二進(jìn)制文件的字節(jié)編碼是機(jī)器語(yǔ)言指令而不是字符。
- 鏈接器,每個(gè)程序不可避免的會(huì)使用到一些標(biāo)準(zhǔn)庫(kù)里的函數(shù)什么的,每個(gè)編譯器都包含了c的標(biāo)準(zhǔn)庫(kù),存放在可重定位目標(biāo)程序格式打包的文件中(我認(rèn)為),將這個(gè)文件和匯編器產(chǎn)生的文件合并,就是鏈接器的作用。然后,結(jié)果是得到了可執(zhí)行目標(biāo)文件,打包格式為可執(zhí)行目標(biāo)程序。
1.3 了解編譯系統(tǒng)如何工作是大有益處的
優(yōu)化程序性能-我們確實(shí)需要了解一些機(jī)器代碼以及編譯器將不同的c語(yǔ)句轉(zhuǎn)化為機(jī)器代碼的方式。
兩種機(jī)器語(yǔ)言:IA32和X86-64,3章學(xué)習(xí)這個(gè),機(jī)器語(yǔ)言,說(shuō)的是機(jī)器語(yǔ)言還是匯編,應(yīng)該是一樣的,匯編和機(jī)器是一一對(duì)應(yīng)的。所以就是機(jī)器語(yǔ)言。
3章學(xué)習(xí)這兩個(gè)語(yǔ)言,5章學(xué)習(xí)如何優(yōu)化程序性能,6章學(xué)習(xí)存儲(chǔ)器系統(tǒng)
3章還將學(xué)習(xí)堆棧原理和緩沖區(qū)溢出錯(cuò)誤,這是大多數(shù)安全漏洞的主要原因。
1.4 處理器讀并解釋存儲(chǔ)在存儲(chǔ)器中的指令
shell是一個(gè)命令行解釋器。
所有系統(tǒng)都有的相同外觀和特性:總線,字長(zhǎng)是一個(gè)基本的系統(tǒng)參數(shù),4字長(zhǎng)就是32位。I/O設(shè)備,每個(gè)I/O設(shè)備都通過(guò)一個(gè)控制器或者適配器與I/O總線相連;控制器是芯片組,或在主板上或在I/O設(shè)備本身上;適配器是插在主板插槽上的卡。
處理器的核心是程序存儲(chǔ)器(PC),是一個(gè)字長(zhǎng)的存儲(chǔ)設(shè)備,或者說(shuō)寄存器。PC中始終存著某條指令的地址。這說(shuō)明一個(gè)事情:地址是一個(gè)字長(zhǎng)的。(至少表面上看是這樣的)。
寄存器文件是由一些1字長(zhǎng)的寄存器組成的。ALU計(jì)算新的數(shù)據(jù)和地址。
CPU執(zhí)行:
- 加載——把一個(gè)字節(jié)或者一個(gè)字從主存復(fù)制到寄存器。
- 存儲(chǔ)——把一個(gè)字節(jié)或者一個(gè)字從寄存器復(fù)制到主存。
- 操作——兩個(gè)寄存器的內(nèi)容復(fù)制給ALU,ALU算術(shù)運(yùn)算,并將結(jié)果存放到一個(gè)寄存器中
- 跳轉(zhuǎn)——從指令本身中抽取一個(gè)字,并復(fù)制到PC中。
3章介紹指令集結(jié)構(gòu)(每條指令的效果),4章介紹微體系結(jié)構(gòu)(處理器的實(shí)現(xiàn))。
1.5 高速緩存至關(guān)重要
意識(shí)到高速緩存存在的應(yīng)用程序員可以利用高速緩存將他們程序的性能提高一個(gè)數(shù)量級(jí)。6章將介紹。
1.6 存儲(chǔ)設(shè)備形成層次結(jié)構(gòu)
每個(gè)計(jì)算機(jī)系統(tǒng)中的存儲(chǔ)設(shè)備都被組織成了一個(gè)存儲(chǔ)器層次結(jié)構(gòu)。
1.7 操作系統(tǒng)管理硬件
操作系統(tǒng)有兩個(gè)基本功能:1防止硬件被失控的應(yīng)用程序?yàn)E用,2應(yīng)用程序提供簡(jiǎn)單一致的機(jī)制來(lái)控制復(fù)雜而又通常大相徑庭的低級(jí)硬件設(shè)備。
操作系統(tǒng)通過(guò)幾個(gè)基本的抽象概念來(lái)實(shí)現(xiàn)這兩個(gè)功能:進(jìn)程,虛擬存儲(chǔ)系統(tǒng),文件。文件抽象I/O設(shè)備,虛擬存儲(chǔ)器抽象文件和主存,進(jìn)程抽象虛擬存儲(chǔ)器和處理器。
系統(tǒng)上只有一個(gè)程序的假象,是通過(guò)進(jìn)程的概念來(lái)實(shí)現(xiàn)的。
進(jìn)程是操作系統(tǒng)對(duì)正在運(yùn)行的程序的一種抽象。操作系統(tǒng)進(jìn)行的抽象。
一個(gè)cpu看上去像是在并發(fā)的執(zhí)行多個(gè)進(jìn)程,這時(shí)通過(guò)處理器在進(jìn)程間切換來(lái)實(shí)現(xiàn)的。操作系統(tǒng)實(shí)現(xiàn)這種交錯(cuò)執(zhí)行的機(jī)制是上下文切換。
上下文是操作系統(tǒng)保持跟蹤進(jìn)程運(yùn)行所需的所有狀態(tài)信息。包括:PC和寄存器文件的當(dāng)前值,主存的內(nèi)容。
單處理器系統(tǒng)在任何時(shí)候都只能執(zhí)行一個(gè)進(jìn)程的代碼。
shell是一個(gè)進(jìn)程,hello是一個(gè)進(jìn)程。8章介紹進(jìn)程的實(shí)現(xiàn)。
每個(gè)線程都運(yùn)行在進(jìn)程的上下文中,并共享同樣的代碼和全局變量。12章學(xué)習(xí)寫(xiě)線程化的程序。
虛擬存儲(chǔ)器為進(jìn)程提供了一個(gè)假象,即每個(gè)進(jìn)程都在獨(dú)占地使用主存。
每個(gè)進(jìn)程看到的是一致的存儲(chǔ)器,稱為虛擬地址空間。一致的,就是說(shuō)一樣的。
在linux中,每個(gè)進(jìn)程看到的虛擬地址空間由大量準(zhǔn)確定義的區(qū)組成。空間從底部向上地址不斷增加。
- 對(duì)于所有的進(jìn)程來(lái)說(shuō),代碼是從同意固定地址開(kāi)始,就是程序的代碼(這里應(yīng)該是編譯后的機(jī)器代碼了)從確定的位置開(kāi)始。也就是虛擬地址空間的底部都具有相同的地址,從這個(gè)地址開(kāi)始首先存放的是代碼,然后是c全局變量。這兩者是按照可執(zhí)行目標(biāo)文件的內(nèi)容初始化的。7章會(huì)學(xué)到更多有關(guān)地址空間的內(nèi)容。
- 在代碼和數(shù)據(jù)后是堆,運(yùn)行時(shí)堆,代碼和數(shù)據(jù)區(qū)在進(jìn)程開(kāi)始的時(shí)候就規(guī)定了大小,這是正常的,因?yàn)榇a和全局變量是不會(huì)變化的。堆會(huì)動(dòng)態(tài)的擴(kuò)展和收縮,c中使用malloc和free這兩標(biāo)準(zhǔn)庫(kù)函數(shù)就會(huì)有這種效果。9章更詳細(xì)的研究堆。
- 大約在地址空間的中間部分是一塊用來(lái)存放像C標(biāo)準(zhǔn)庫(kù)和數(shù)學(xué)庫(kù)這樣共享庫(kù)的代碼和數(shù)據(jù)的區(qū)域。也是代碼和數(shù)據(jù)的區(qū)域。7章將學(xué)習(xí)共享庫(kù)是如何工作的。
- 位于用戶虛擬地址空間頂部的是用戶棧,編譯器用它來(lái)實(shí)現(xiàn)函數(shù)調(diào)用。也會(huì)收縮和擴(kuò)展,調(diào)用一個(gè)函數(shù)時(shí)就增長(zhǎng),從一個(gè)函數(shù)返回時(shí)就收縮。這里的棧是在頂部,用戶虛擬地址空間的頂部,上面還有內(nèi)核虛擬存儲(chǔ)器,這個(gè)不管,在用戶虛擬地址空間的頂部說(shuō)明棧是向下增長(zhǎng)的,而堆緊靠著代碼和數(shù)據(jù)區(qū)說(shuō)明堆是向上增長(zhǎng)的,兩者中間是共享庫(kù)區(qū),好理解。3章學(xué)習(xí)編譯器是如何使用棧的。
- 內(nèi)核總是駐留在內(nèi)存中的,是操作系統(tǒng)的一部分,地址空間頂部的區(qū)域(不是用戶虛擬地址空間,而是虛擬地址空間)是為內(nèi)核保留的,不允許應(yīng)用程序讀寫(xiě)這個(gè)區(qū)域的內(nèi)容或者直接調(diào)用內(nèi)核代碼定義的函數(shù)。應(yīng)用程序只能使用操作系統(tǒng)提供的統(tǒng)一的接口吧,這些接口既然不在內(nèi)核中(因?yàn)椴荒苁褂脙?nèi)核代碼),所以應(yīng)該在共享庫(kù)中。
9章將詳細(xì)解釋虛擬存儲(chǔ)器系統(tǒng)如何工作。
文件就是字節(jié)序列,僅次而已。I/O設(shè)備可以視為文件。
系統(tǒng)中所有輸入和輸出都是通過(guò)使用一小組稱為Unix I/O的系統(tǒng)函數(shù)調(diào)用讀寫(xiě)文件來(lái)實(shí)現(xiàn)的。
這里有個(gè)概念,I/O就是輸入和輸出,I/O設(shè)備就是可以輸入和輸出的設(shè)備。而文件可以讀和寫(xiě),讀和寫(xiě)又可以看作是輸出和輸入。所以,I/O設(shè)備與文件具有核心的共性。所以可以抽象。10章介紹Unix I/O。
1.8 系統(tǒng)之間利用網(wǎng)絡(luò)通信
網(wǎng)絡(luò)可以視為一個(gè)I/O設(shè)備,適配器就是網(wǎng)絡(luò)適配器(網(wǎng)卡,有線的或者無(wú)線的),而網(wǎng)絡(luò)就是一個(gè)I/O設(shè)備。11章講學(xué)到如何構(gòu)造網(wǎng)絡(luò)應(yīng)用程序,并利用這些知識(shí)創(chuàng)建一個(gè)簡(jiǎn)單的web服務(wù)器。
1.9 重要主題
系統(tǒng)是硬件和軟件相互交織的集合體。系統(tǒng)又是硬件和應(yīng)用程序之間的一層軟件。系統(tǒng)可以有很多名字。
在此再次強(qiáng)調(diào)幾個(gè)貫穿計(jì)算機(jī)系統(tǒng)所有方面的重要概念:
并發(fā)(concurrency)指同時(shí)具有多個(gè)活動(dòng)的系統(tǒng)。并行指用并發(fā)使系統(tǒng)更快。并行可以在計(jì)算機(jī)系統(tǒng)的多個(gè)抽象層次上運(yùn)用。從高到低的三個(gè)層次:
線程級(jí)并發(fā):單處理器系統(tǒng)--只有一個(gè)處理器的系統(tǒng),這種系統(tǒng)也是可并發(fā)的,因?yàn)楸热绫?的單核系統(tǒng)就可以變聽(tīng)歌邊上網(wǎng)。但這種并發(fā)是模擬出來(lái)的,是的,這就是模擬出來(lái)了,是單處理器在不同進(jìn)程之間不斷切換來(lái)實(shí)現(xiàn)的,這種就叫模擬出來(lái)的并發(fā)。
多處理器系統(tǒng)分兩種:多處理器和超線程。
- 多處理器是一個(gè)集成電路芯片上有多個(gè)核(cpu),一個(gè)核完整的應(yīng)該是計(jì)算單元,寄存器文件,L1高速緩存(L2高速緩存);這稱為一個(gè)核,一個(gè)cpu。
- 超線程是指一個(gè)核執(zhí)行多個(gè)控制流的技術(shù),事實(shí)上,一個(gè)進(jìn)程中多個(gè)控制流就指多個(gè)線程。這個(gè)時(shí)候的核可以只有一個(gè)計(jì)算單元,但是寄存器文件和L1高速緩存可能就有多組,由于內(nèi)存中共用虛擬地址空間(一個(gè)進(jìn)程嗎)所以幾組寄存器和L1高速緩存就可以有幾組線程。常規(guī)的處理器需要大約20000個(gè)時(shí)鐘周期來(lái)做不同線程間的切換,而這種超線程技術(shù)的處理器之用一個(gè)周期。
這種多處理器系統(tǒng)才可以說(shuō)是真的做到了并發(fā)吧。
指令級(jí)并行;這個(gè)微機(jī)原理中其實(shí)講的比較清楚,就是取指令和處理指令其實(shí)是分開(kāi)的,多條指令的不同步驟可以同時(shí)的進(jìn)行,這個(gè)就是指令級(jí)并行,4章研究流水線的使用,5章介紹超標(biāo)量處理器的高級(jí)模型。
單指令/多數(shù)據(jù)并行:一條指令可以產(chǎn)生多個(gè)可以并行執(zhí)行的操作。上面的是多個(gè)指令并行的執(zhí)行,這個(gè)是一個(gè)指令的不同部分并行的執(zhí)行。SIMD并行。
最高級(jí)別是線程級(jí)并發(fā),其實(shí)多核就是進(jìn)程級(jí)的并發(fā)了,超線程是線程級(jí)的并發(fā)。再往上,就沒(méi)有了。進(jìn)程已經(jīng)到頂了。
抽象是計(jì)算機(jī)科學(xué)中最為重要的概念之一。
指令集結(jié)構(gòu)是對(duì)實(shí)際硬件的抽象,表示的是執(zhí)行模型。兩個(gè)處理器的執(zhí)行模型一樣不代表實(shí)際硬件的實(shí)現(xiàn)方式一樣,雖然由于執(zhí)行模型相同,也就是指令集相同,所有可以執(zhí)行相同的機(jī)器語(yǔ)言代碼,但是卻有不同的開(kāi)銷(xiāo)和性能。
1.10 小結(jié)
(OVER)
轉(zhuǎn)載于:https://www.cnblogs.com/rayhill/archive/2012/04/15/2450641.html
總結(jié)
以上是生活随笔為你收集整理的csapp第一章 计算机系统漫游 学习和理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 通过eclipse手工生成osgi-bu
- 下一篇: 蜻蜓特派员 Windows XP SP3