一條主線:跟蹤hello程序的生命周期來開始對系統的學習。
1 信息的表示
hello.c的表示方法說明了一個基本思想:系統中所有的信息——包括磁盤文件、存儲器中的程序、存儲器中存放的用戶數據以及網絡上穿傳送的數據,都是由一串位表示的。區分不同數據對象的唯一方法就是我們讀到這些數據對象時的上下文。
數字的機器表示方式與實際的整數和實數是不同的,它們是對真值的有限近似值,有時候會有意想不到的行為表現。
2 編譯
1)預處理階段
預處理器cpp根據#開頭的命令,修改原始C程序。
2)編譯階段
編譯器ccl將源程序編譯成匯編語言
3)匯編階段
匯編器as將匯編語言翻譯成機器語言指令,把這些指定打包成可重定位目標程序
4)鏈接階段
將需要的庫函數鏈接進來,形成最終的可執行目標文件
了解編譯系統的好處:
1)優化程序性能
2)理解鏈接時出現的錯誤
3)避免安全漏洞
3 執行
shell加載hello程序
3.1 系統的硬件組成
a.總線
總線攜帶信息字節并負責在各個部件間傳遞
b.I/O設備
用戶輸入:鍵盤、鼠標
用戶輸出:顯示器
存儲:磁盤驅動器(hello程序位置)
每個I/O設備都通過一個控制器或適配器與I/O總線相連。控制器和適配器之間主要區別在于它們的封裝方式。控制器是置于I/O設備本身的或者主板上的芯片組,而適配器則是一塊插在主板插卡槽上的卡。總之,它們的主要功能都是在I/O總線和設備之間傳遞信息。
c.主存
在處理器執行程序時,用來存放程序和程序處理的數據。DRAM
d.處理器
CPU,是解釋(執行)存儲在主存中指令的引擎。
核心是PC(程序計數器),任何時候,PC都指向主存中某條機器語言指令。
處理器從PC指向的主存處讀取指令,解釋指令中的位,執行該指令指示的簡單操作,然后更新PC,使其指向下一條指令。
CPU在指令的要求下可能執行以下操作:
- 加載:把一個字節或者字從主存復制到寄存器,以覆蓋寄存器原來的內容
- 存儲:把一個字節或者字從寄存器復制到主存的某個位置,以覆蓋原來的內容
- 操作:把兩個寄存器的內容復制到ALU,ALU對這兩個字做算術操作,并將結果存放到一個寄存器,以覆蓋寄存器原來的內容
- 調整:從指令本身抽取一個字,并將這個字復制到PC中,以覆蓋PC中原來的值
處理器看上去知識它的指令集結構的簡單實現,但是實際上現代處理器使用了非常復雜的機制來加速程序的執行。可以區分處理器的指令集結構和微體系結構:
- 指令集結構:描述的是每條機器代碼指令的效果
- 微體系結構:描述的是處理器實際上是如何實現的
3.2 運行hello程序
step1.shell輸入"./hello"
shell將字符逐一讀入寄存器,再把它放到主存中
step2.敲入回車后
shell執行一系列指令來加載可執行的hello文件,將hello目標文件中的代碼和數據從磁盤復制到主存。
利用DMA(直接存儲器存儲)技術,數據可以不通過處理器直接從磁盤到達主存。
step3.加載到主存后的執行
hello中的代碼和數據被加載主存,處理器就開始執行hello程序的main程序中的機器語言指令。
這些指令將“hello, world\n”字符串字節從主存復制到寄存器文件,再從寄存器文件中復制到顯示設備,最終顯示到屏幕上。
4 存儲
hello程序指令:磁盤->主存->處理器
hello程序數據:磁盤->主存->顯示設備 (中間省略了寄存器)
這些復制工作就是開銷,因此,系統設計者的一個主要目標就是使這些復制操作盡可能快地完成。
針對處理器與主存之間的差異(1000倍速度),加入高速緩存(SRAM),存放處理器近期可能會需要的信息。
存儲器的層次結構(存儲器層次結構的主要思想是某一層的存儲器作為低一層存儲器的高速緩存):
5 操作系統管理硬件
shell和hello程序都沒有直接訪問鍵盤、顯示器、磁盤或者主存。取而代之,它們依靠操作系統提供的服務。
操作系統有兩個基本功能:
1)防止硬件被失控的應用程序濫用
2)向應用程序提供簡單一致的機制來控制復雜而又通常大相徑庭的低級硬件設備
操作系統通過幾個基本的抽象概念(進程、虛擬存儲器、文件)來時間這兩個功能。
1)文件是對I/O設備的抽象
2)虛擬存儲器是對主存和磁盤I/O設備的抽象表示
3)進程則是對處理器、主存和I/O設備的抽象表示
5.1 進程和線程
進程是操作系統對一個正在運行的程序的一種抽象。
操作系統實現進程的交錯執行的機制成為上下文切換,操作系統保持跟蹤進行運行所需的所有狀態信息(上下文)。
shell進程和hello進程的運行場景:
step1.只有shell進程,輸入命令
step2.shell進行系統調用,來執行請求,系統調用會將控制權傳遞給操作系統,操作系統保存shell的上下文,創建一個新的hello進程及其上下文
step3.控制權傳遞給hello進程
step4.hello進程中之后,操作系統恢復shell進程的上下文,并將控制權傳回給shell,shell將繼續等待下一個命令行的輸入
線程:線程之間比進程之間更容易實現共享數據,因此一般更高效。
5.2 虛擬存儲器
虛擬存儲器為每個進程提供一個假象(虛擬地址空間),即每個進程都在獨占地使用主存。
基本思想:把一個進程虛擬存儲器的內容存儲在磁盤上,然后用主存作為磁盤的高速緩存
從低地址往上,進程的各個區分別是:
1)程序代碼和數據。代碼從同一固定位置開始,緊接著是全局變量
2)堆。代碼和數據區后緊隨著運行時堆。
3)共享庫。大約在地址空間的中間一部分是一塊用來存放像C標準庫和數學庫的代碼和數據的區域。
4)棧。位于用戶虛擬地址空間頂部的是用戶棧,編譯器用它來實現函數調用。
5)內核虛擬存儲器。內核總是駐留在內存中,地址空間頂部的區域是為內核保留。不允許應用程序讀寫這個區域的內容或者直接調用內核代碼定義的函數。
5.3 文件
文件就是字節序列,僅此而已。
每個I/O設備,包括磁盤、鍵盤、顯示器,甚至網絡,都可以視為文件。
6 通信(網絡也是一種I/O設備)
例如使用telnet應用在一個遠程主機上運行hello程序。
7 幾個重要的主題
7.1 并發和并行
計算機發展歷史中,有兩個需求是驅動進步的持續動力:
- 我們想要計算機做的更多
- 我們想要計算機運行得更快
并發:指一個同時具有多個活動的系統
并行:用并發使一個系統運行更快
1)線程級并行
多處理器的使用要求程序以多線程的方式來書寫。
2)指令級并行(流水線、超標量)
現代處理器可以同時執行多條指令的屬性成為指令級并行
3)單指令、多數據并行(向量數據類型)
許多現代處理器擁有特殊的硬件,運行一條指令產生多個可以并行執行的操作:單指令、多數據(SIMD)。提供SIMD指令是為了提高處理影像、聲音和視頻數據應用的執行速度。