概念:計算機系統是由硬件和軟件組成的,它們共同工作來運行應用程序。
目標:理解底層計算機系統的本質和如何影響應用程序。
從本書可以學到:
- 一些實踐技巧,比如如何避免由計算機表示數字方式引起的奇怪的數字錯誤;
- 通過一些運用了現代處理器和存儲器系統的設計的小竅門來優化C代碼;
- 瞭解到編譯器是如何實現過程調用的,並且瞭解到如何利用這個知識來避免緩存區溢出錯誤帶來的安全漏洞;
- 學會如何認識和避免鏈接時那些令人討厭的錯誤;
- 學會如何編寫自己的Unix shell、自己的動態存儲分配包,甚至於自己的Web服務器
- ……
1.1 信息就是位+上下文
- hello源程序實際上就是一個由0和1組成的位(又稱爲bit/比特)序列,這些位八日組織成8個一組,稱爲字節。每個字節都表示程序中某個文本字符。
- ASCII標準碼其實就是用一個唯一的字節大小的整數值來表示每個字符。
- hello.c程序是以字節序列的方式儲存在文件中的。
- 系統中所有的信息——包括磁盤文件、存儲器中的程序、存儲器中存放的用戶數據以及網絡上傳送的數據,都是由一串比特表示的。區分不同數據對象的唯一方法是我們讀到這些數據對象時的上下文。
1.2 程序被其他程序翻譯成不同的格式
- 爲了在系統上運行hello.c程序,每條C語句都必須都被其他程序轉化爲一系列的低級機器語言指令。然後這些指令按照一種稱爲可執行目標程序(executable object program)的格式打包好,並以二進制磁盤文件的形式存放起來。目標程序也稱爲可執行目標文件(executable object file)。
編譯系統構成:
- 預處理器:hello.c --> hello.i
- 編譯器:hello.i --> hello.s
- 彙編器:hello.s --> hello.o
- 鏈接器:hello.o --> hello(可執行目標程序)
四個階段:
- 預處理階段:預處理器根據字符#開頭的命令(directives)修改原始的C程序。
- 編譯階段:將文本文件hello.i翻譯成文本文件hello.s,它包含一個彙編語言程序。
- 彙編階段:彙編器將hello.s翻譯成機器語言指令。把這些指令打包成一種叫做可重定位(relocatable)目標程序地格式,並將結果保存在目標文件hello.o中。
- 鏈接階段:鏈接器負責將預編譯目標文件併入到hello.o程序中,結果得到hello文件。
可執行文件加載到存儲器後,由系統負責執行。
1.3 瞭解編譯系統如何工作是大有益處的
- 促使程序員必須知道編譯系統是如何工作的原因:
- 優化程序性能。
- 理解鏈接時出現的錯誤。
- 避免安全漏洞。
1.4 處理器讀出並解釋儲存在存儲器中的指令
1.4.1 系統的硬件組成
- 總線
- 貫穿整個系統的是一組電子管道,稱作總線,它攜帶信息字節並負責在各個部件間傳遞。
- I/O設備
- I/O設備是系統與外界的聯繫通道。
- 每個I/O設備都是通過一個控制器或適配器與I/O總線連接起來的,功能是在I/O總線和I/O設備之間傳遞信息。
- 主存
- 主存是一個臨時存儲設備,在處理器執行程序時,它被用來存放程序和程序處理的數據。
- 處理器
- 中央處理單元(CPU)簡稱處理器,是解釋存儲在主存中指令的引擎。
- 寄存器文件是一個小的存儲設備,由一些字長大小的寄存器組成,這些寄存器每個都有唯一的名字。
1.4.2 執行hello程序
1.5 高速緩存
- 系統設計的一個主要目標就是使拷貝操作儘可能的快。
- 這本書重要的課題之一就是應用程序員通過理解高速緩存存儲器的機理,能夠利用這些知識極大地提高程序的性能。
1.6 形成層次結構的存儲設備
- 存儲器分層結構的主要思想是一個層次上的存儲器作爲下一層次上的存儲器的高速緩存。
1.7 操作系統管理硬件
- 可以把操作系統看成是應用程序和硬件之間插入的一層軟件,所有應用程序對硬件的操作嘗試都必須通過操作系統。
- 操作系統有兩個基本功能:防止硬件被失控的應用程序濫用;在控制複雜而又通常廣泛不同的低級硬件設備方面,爲應用程序提供簡單一致的方法。
- 操作系統通過幾個基本的抽象概念(進程、虛擬存儲器和文件)實現這兩個功能。
- 文件是對I/O設備的抽象表示
- 虛擬存儲器是對主存和磁盤I/O設備的抽象表示
- 進程是對處理器、主存和I/O設備的抽象表示
1.7.1 進程
- 進程是操作系統對運行程序的一種抽象。
- 在一個系統上可以同時運行多個進程,而每個進程都好像在獨佔地使用硬件。我們稱之爲併發運行,實際上是說開一個進程的指令和另一個進程的指令是交錯執行的。操作系統實現這種交錯執行的機制稱爲上下文切換(context switching)。
1.7.2 線程
- 現代系統中,一個進程實際上可以由多個稱爲線程的執行單元組成,每個線程都運行在進程的上下文中,並共享同樣的代碼和全局數據。
1.7.3 虛擬存儲器
- 虛擬內存器是一個抽象概念,它爲每個進程提供了一個假象,好像每個進程都在獨佔地使用內存。每個進程看到的存儲器都是一致的,稱之爲虛擬地址空間。
- 虛擬空間區域:
- 程序代碼和數據
- 堆
- 共享庫
- 棧:位於用戶虛擬地址空間頂部的是用戶棧,編譯器用它來實現函數調用。
- 內核虛擬存儲器:內核是操作系統總是駐留在存儲器中的部分。應用程序不允許讀寫這個區域的內容或者直接調用內核代碼定義的函數。
1.7.4 文件
1.8 利用網絡系統和其他系統通信
1.9 下一步
- 系統是互相交織的硬件和系統軟件的集合體,它們必須共同給協作以達到運行應用程序的最終目的。
1.10 小結
- 操作系統內核是應用程序和硬件之間的媒介。