1. 程式人生 > >《深入理解計算機系統》筆記——計算機系統漫遊

《深入理解計算機系統》筆記——計算機系統漫遊

1.計算機系統

由硬體與軟體組成,他們共同工作來執行程式。

2.資訊的表示

#include <stdio.h>
 
int main()
{
 printf("Hello World\n");
 return 0;    //c標準規定建議main函式返回值為int
} 

編寫程式時將上面的 Hello World 程式儲存在一個 hello.c 的檔案中,他將以字序列方式儲存在檔案中。

:由若干個位元組構成,字的位數叫做字長,不同檔次的機器有不同的字長。例如一臺8位機,它的1個字就等於1個位元組,字長為8位。如果是一臺16位機,那麼,它的1個字就由2個位元組構成,字長為16位。在32位作業系統當中,一個字是4個位元組,字是計算機進行資料處理和運算的單位。

位元組:8個二進位制位構成1個"位元組(Byte)",它是儲存空間的基本計量單位。1個位元組可以儲存1個英文字母或者半個漢字,換句話說,1個漢字佔據2個位元組的儲存空間。

:"位(bit)"是電子計算機中最小的資料單位。每一位的狀態只能是0或1。

我們將hello.c檔案變為用ASCII碼錶示:
在這裡插入圖片描述
例如:0x23對應表示的是‘#’字元
hello.c檔案等這類由ADSCII碼組成的檔案稱為“文字檔案”,其他稱之為“二進位制檔案”。

2.1系統中所有的資訊都是由位+上下文構成

包括磁碟檔案、儲存器中的程式,儲存器中存放的使用者資料以及網路上傳送的資料都是由一串位來表示。而區分不同資料物件的唯一方法就是他們對應的上下文

,在不同的上下文中,一個同樣的位元組序列可能表示不同的內容。

3.程式的編譯

我們將要將 hello.c 變成一個可執行的目標程式,他就必須要經過 前處理器cpp、編譯器ccl、彙編器as、連結器ld 的處理。

1.預處理階段:前處理器 cpp 根據以字元 # 開頭的命令,修改原始的 C 程式、得到新的hello.i

2.編譯階段:編譯器 ccl 將文字檔案 hello.i 翻譯成文字檔案 hello.s,它包含一個組合語言程式,組合語言程式中的每條語句都以一種標準的文字格式確切的描述一條低階機器語言指令。組合語言能為不同高階語言的不同編譯器提供通用的輸出語言。

3.彙編階段:彙編器 as 將hello.s 翻譯成機器語言指令,把這些指令打包成一種叫做可重定位目標程式的格式,並將結果儲存在目標檔案 hello.o 中,hello.o 檔案是一個二進位制檔案,它的位元組編碼是機器預言指令而不是字元。如果我們用文字編輯器開啟 hello.o 檔案,將會是一堆亂碼。

4.連結階段:在 hello.c 程式中,程式呼叫了 printf 函式,printf 函式存在於一個名為 printf.o 的單獨的預編譯好了的目標檔案中,而這個檔案必須以某種方式合併到我們的 hello.o 程式中。連結器 ld 就是負責處理這種合併,結果就得到一個 hello 檔案,它是一個可執行的目標程式。

過程:hello.c->hello.i->hello.s->hello

4.程式的執行

hello.c經過上面的過程編譯已經變為了hello程式放在了磁碟上。
圖為書中程式執行的過程
在這裡插入圖片描述
在這裡插入圖片描述
圖內出現名稱解析:

1.匯流排:貫穿整個系統的一組電子管道,通常被設計成用來傳送定長的位元組塊,也就是字。字的大小與系統相關,比如在32位作業系統當中,一個字是4個位元組。

2. I/O裝置:輸入/輸出(I/O)裝置是系統與外部世界聯絡通道,圖有4個I/O裝置(滑鼠 鍵盤 顯示器 磁碟)。每一個I/O裝置都通過一個控制器或者介面卡與I/O匯流排相連。控制器是置於I/O裝置本身的或者系統的主印刷電路板(通常稱為主機板)上的晶片組,而介面卡則是一塊插在主機板插槽上的卡。無論如何,它們的功能都是在 I/O 匯流排和 I/O 裝置之間傳遞資訊。

3.主存:它是計算機中的一個臨時儲存裝置,在處理器執行程式的時候,用來存放程式和程式處理的資料。物理上來說,主存是由一組動態隨機存取儲存器(DRAM)組成的,邏輯上來說,它是一個線性的位元組陣列,每一個位元組都有唯一的地址(即陣列索引)。

4. 處理器:全稱中央處理器(CPU),是解釋(或執行)儲存在主存中指令的引擎。處理器的核心是一個字長的儲存裝置(或暫存器),簡稱程式計數器(PC),在任何時刻,它都會指向主存中的某條機器指令(即含有該條指令的地址)。從系統通電到斷點,處理器一直在不斷的執行程式計數器所指向指令,再更新程式計數器,使其指向下一條指令。處理器所做的操作是圍繞主存、暫存器檔案以及算術/邏輯單元(ALU)進行的,暫存器檔案是一個小的儲存裝置,由一些1字長的暫存器組成,每個暫存器都有唯一的名字。ALU則計算新的資料和地址值。

5.儲存裝置

5.1 從磁碟載入可執行檔案到主存

在這裡插入圖片描述

5.2 將輸出字串從記憶體寫到顯示器

在這裡插入圖片描述

5.3 快取記憶體儲存器

資料的傳輸就是資料的複製過程。從寫入到儲存在暫存器檔案花費很多時間來執行。
那麼如何減少這種由資料複製所引起的開銷呢?
機械原理,較大的儲存裝置比較小的儲存裝置執行的慢,我們通常會在快取記憶體儲存器(簡稱快取記憶體),作為暫時的集結區域,用來存放處理器近期可能會需要的資訊
在這裡插入圖片描述

5.4 儲存裝置的金字塔結構

在這裡插入圖片描述
每一層快取記憶體都為下一級的快取記憶體(如 L1為L2的快取記憶體)。

6.作業系統

我們可以把作業系統看成應用程式和硬體之間插入的一層軟體,如圖:
在這裡插入圖片描述

作業系統的兩個基本功能:

①、防止硬體被失控的應用程式濫用。

②、嚮應用程式提供簡單一致的機制來控制複雜而又大相徑庭的低階硬體裝置。

7.程序

當我們執行hello程式時,作業系統給我們提供一種假象,就好像系統只有這個程式在執行,而這種假象是通過程序的概念來實現的。
實際上,他們是併發的在執行,即一個程序的指令和另一個程序的指令是交錯執行的。
在這裡插入圖片描述
在單CPU系統中,系統在一個時刻只能執行一個程序,多CPU系統中,系統則是能夠同時處理多個程序。但無論是單核還是多核,一個CPU只能併發的執行多個程序,這是通過處理器在程序間切換來實現的。而作業系統實現這種交錯機制稱為上下文切換
在這裡插入圖片描述

程序A與程序B在併發進行,程序通過上下文來回切換。

8.虛擬儲存器

虛擬儲存器是一個抽象概念,它為每個程序提供了假象,即每個程序都在獨佔的使用主存。
 每個程序看到的是一致的儲存器,稱為虛擬地址空間。在這裡插入圖片描述
 圖中出現的名詞解析:

程式程式碼和資料:對於所有程序來說,程式碼是從同一固定地址開始的,分別為0x08048000(32位)以及0x00400000(64位),緊接著是全域性變數相對應的資料位置。

:程式碼和資料區後緊隨的是執行時堆。程式碼和資料區是在程序一開始執行時就規定了大小,而當呼叫malloc和free這樣的 C 標準庫函式 時,堆可以在執行時動態的擴充套件和收縮。

共享庫:存放像C標準庫和資料庫這樣的程式碼和資料的區域。

:位於使用者虛擬地址空間頂部,編譯器用它來實現函式呼叫,使用者棧在程式執行期間可以動態的擴充套件和收縮。當我們呼叫一個函式時,棧會增長;從一個函式返回時,棧會收縮。

核心虛擬儲存器:核心總是駐留在記憶體中,是作業系統的一部分,不允許應用程式讀寫這個區域的內容或者直接呼叫核心程式碼定義的函式。

9.計算機系統中抽象的重要性

抽象的使用是電腦科學中最重要的概念之一。例如,為一組函式規定一個簡單的應用程式介面API就是一個很好的程式設計習慣。程式設計師無需瞭解它內部的工作原理便可以使用這些程式碼。這在Java當中的典型比如類的定義,C語言中的函式原型。
  在這裡插入圖片描述

10.結束

那麼深入理解計算機系統第一章計算機系統的漫遊將到此結束,之後的每一部分每一章會對之間內容詳細講解。