一物咳、整本書的結(jié)構(gòu)
- 1.Chapter01:計算機(jī)系統(tǒng)漫游
- 2.Chapter02~Chapter12
- Part I:程序結(jié)構(gòu)和執(zhí)行(Chapter02~Chapter06)
- Part II:在系統(tǒng)上運行程序(Chapter07~Chapter09)
- Part III:進(jìn)程間的交互和通信(Chapter10~Chapter12)
二、程序編譯流程
- 1.編譯系統(tǒng)工作流程
Stage1(預(yù)處理):預(yù)處理器會根據(jù)以#開頭的代碼,來修改原始程序,預(yù)處理器會讀取頭文件中的內(nèi)容,將頭文件中的內(nèi)容直接插入到源程序中,結(jié)果就得到了另一個C程序。經(jīng)預(yù)處理器處理后得到的文件通常以.i為后綴結(jié)尾闹丐,它仍然是一個文本文件;
Stage2(編譯):編譯器將hello.i文件翻譯成hello.s文件被因,這一過程稱為編譯卿拴。其中編譯這一階段包括詞法分析衫仑、語法分析、語義分析堕花、中間代碼生成及優(yōu)化等一系列的中間操作文狱;
Stage3(匯編):匯編器根據(jù)指令集將匯編程序hello.s翻譯成機(jī)器指令,并且把這一系列的機(jī)器指令按照固定的規(guī)則進(jìn)行打包得到可重定位目標(biāo)文件hello.o航徙。此時如贷,雖然hello.o是一個二進(jìn)制文件,但是還不能執(zhí)行還需要進(jìn)行鏈接操作到踏;
Stage4(鏈接):在hello這個程序中,調(diào)用了標(biāo)準(zhǔn)C庫中的函數(shù)printf尚猿,每一個C語言的編譯器都會提供窝稿。當(dāng)調(diào)用printf函數(shù)時,編譯器就知道你要在屏幕上打印輸出內(nèi)容凿掂,它會將這行代碼翻譯成計算機(jī)可以理解的指令伴榔。printf函數(shù)在名為printf.o文件中,這個文件是一個提前編譯好的目標(biāo)文件庄萎。鏈接器ld負(fù)責(zé)把hello.o和printf.o進(jìn)行合并踪少,但合并需要遵循一定的規(guī)則。正是由于鏈接器要對hello.o和printf.o進(jìn)行調(diào)整糠涛,所以hello.o才會稱為可重定位目標(biāo)文件援奢,最終經(jīng)過鏈接階段可以得到可執(zhí)行目標(biāo)文件hello。此時忍捡,得到的hello就可以被加載到內(nèi)存中執(zhí)行了集漾。
-
2.理解編譯系統(tǒng)工作流程的意義
- 優(yōu)化程序性能;
- 理解鏈接時出現(xiàn)的錯誤砸脊;
- 避免安全漏洞(緩沖區(qū)溢出)具篇;
三、計算機(jī)系統(tǒng)的硬件組成
-
1.CPU的結(jié)構(gòu)
程序計數(shù)器PC:一個字即4字節(jié)(32位系統(tǒng))或一個字即8字節(jié)(64位系統(tǒng))的存儲空間凌埂,里面存放的是某一條指令的地址驱显。從系統(tǒng)上電的那一瞬間到系統(tǒng)斷電,處理器就不斷地在執(zhí)行PC執(zhí)向的指令瞳抓,然后更新PC埃疫,使其指向下一條要指向的指令。注意:下一條執(zhí)行的指令與剛剛執(zhí)行過的指令不一定是相鄰的地址挨下。
寄存器文件:它是CPU內(nèi)部的一個存儲設(shè)備熔恢,寄存器文件是由一些單字長的寄存器構(gòu)成,每個寄存器都有自己唯一的名字臭笆。換句話說叙淌,寄存器可以理解為一個臨時存放數(shù)據(jù)的空間秤掌。
算術(shù)邏輯單位ALU:例如,計算兩個變量a鹰霍、b的和闻鉴,處理器從內(nèi)存中讀取a的值暫存在寄存器X中,讀取b的值暫存在寄存器Y中茂洒,這個操作會覆蓋寄存器中原來的數(shù)值孟岛。處理器完成加載的操作后,ALU會復(fù)制寄存器X和Y中保存的數(shù)值督勺,然后進(jìn)行算術(shù)運算渠羞,得到的結(jié)果會保存在寄存器X或寄存器Y中。此時智哀,寄存器中原來的值會被新的值所覆蓋次询。
-
2.主存/內(nèi)存
- 處理器在執(zhí)行程序時,內(nèi)存主要存放程序指令和數(shù)據(jù)瓷叫。從物理上來說屯吊,內(nèi)存就是由隨機(jī)動態(tài)存儲芯片組成;從邏輯上來說摹菠,內(nèi)存可以看成是一個從0開始的大數(shù)組盒卸,每個字節(jié)都有相應(yīng)的地址。
-
3.總線
- 內(nèi)存和處理器之間通過總線來進(jìn)行數(shù)據(jù)傳遞次氨,總線貫穿了整個計算機(jī)系統(tǒng)蔽介,它負(fù)責(zé)將信息從一個部件傳遞到另一個部件,通吃阈瑁總線被設(shè)計成固定長度的字節(jié)塊即字word屉佳。字表示多少個字節(jié),各個系統(tǒng)是不一樣的洲押。
-
4.輸入輸出設(shè)備
- 例如:鍵盤武花、鼠標(biāo)、顯示器等杈帐,每個輸入輸出設(shè)備都通過一個控制器或者適配器與IO總線相連体箕。
四、hello程序執(zhí)行時挑童,究竟發(fā)生了什么累铅?
- 1.鍵盤輸入./hello時,shell程序會將輸入的字符逐一讀入寄存器站叼,處理器會把這個hello字符串放入內(nèi)存中娃兽;
- 2.當(dāng)完成輸入,按下回車鍵時shell程序已經(jīng)知道我們已經(jīng)完成了命令的輸入尽楔,然后執(zhí)行一系列的指令來加載可執(zhí)行文件hello投储。 這些指令將hello中的數(shù)據(jù)和代碼從磁盤復(fù)制到內(nèi)存第练。數(shù)據(jù)就是要在屏幕上顯示的“hello world\n”,這個復(fù)制的過程將利用DMA技術(shù)玛荞,數(shù)據(jù)可以不經(jīng)過處理器娇掏,從磁盤直接到達(dá)內(nèi)存;
- 3.當(dāng)可執(zhí)行文件hello中的代碼和數(shù)據(jù)被加載到內(nèi)存中勋眯,處理器就開始執(zhí)行main函數(shù)中的代碼婴梧。CPU會將“hello world\n”這個字符串從內(nèi)存復(fù)制到寄存器文件,再從寄存器文件復(fù)制到顯示設(shè)備即屏幕上客蹋;
五塞蹭、緩存問題
1.通常情況下,大容量的存儲設(shè)備存取速度要比小容量的慢讶坯;運行更快設(shè)備的價格相對于運行速度慢的設(shè)備的價格要貴浮还;
2.內(nèi)存的層級結(jié)構(gòu)
-
針對處理器和內(nèi)存之間的讀寫速度差異,系統(tǒng)設(shè)計人員在寄存器文件和內(nèi)存之間引入了高速緩存cache闽巩。比較新且處理能力比較強(qiáng)的處理器,一般有三級高速緩存:L1 cache担汤、L2 cache涎跨、L3 cache。L1 cache的訪問速度與訪問寄存器文件幾乎一樣快崭歧,L2 cache的訪問速度是L1的5倍隅很,L3 cache的容量更大,訪問速度與L2 cache相比更慢率碾。
寄存器文件Register File 100~1000B L1 cache 10~100KB L2 cache 0.1 ~10MB L3 cache 10~100MB 內(nèi)存Main Memory 1~100GB 磁盤Disk 1~1000TB