計算機系統初步介紹

計算機是由硬件和系統軟件組成,它們共同工作來運行應用程序。

我們來通過hello程序生命周期,了解當系統在執(zhí)行hello程序時,系統發(fā)生了什么以及為什么會如此運作。

#include <stdio.h>

int main()
{
    printf("hello world\n");
}

一、信息是位+上下文

hello程序時從源程序(源文件)開始,源程序由程序員通過編輯器創(chuàng)建并保存為文本文件,文件名為hello.c。源程序實際上是由0和1組成的位(亦比特)序列,這些位被組織成8個一組,稱為字節(jié),每個字節(jié)表示程序中某個文本字符。

大部分程序采用ASCII標準來表示文本字符,用唯一的字節(jié)大小的整數值表示每個字節(jié)。

hello.c以字節(jié)序列方式存儲在文件中,每個字節(jié)都有一個整數值,對應于某個字符。例如,第一個字節(jié)的整數值是35,對應字符#。每行文本都是以一個看不見換行符"\n"來結束,對應的整數值為10。

hello.c的標識方法說明一個基本思想:系統中所有的信息-----包含磁盤文件、存儲器中的程序、存儲器中存放的用戶數據以及網絡上傳送的數據,都是由一串比特表示的。區(qū)分不同數據對象的唯一方法,讀到這些數據對象時上下文。

二、程序被其他程序翻譯成不同格式

為了在系統上運行hello.c程序,每條C語句都必須被其他程序轉化為一系列的低級機器語言指令,這些指令按照可執(zhí)行目標程序的格式打包,并以二進制磁盤文件的形式存放起來。

在Unix系統上,從源文件到目標文件的轉化是由編譯器驅動程序完成,

unix> gcc -0 hello hello.c

gcc編譯器驅動程序讀取源程序文件hello.c,翻譯成一個可執(zhí)行目標文件hello,這個翻譯過程分為四個階段完成,預處理器、編譯器、匯編器、鏈接器。

編譯系統.jpg
  • 預處理階段。預處理(cpp)根據字符#開頭的命令,修改原始C程序,直接插入到程序文本中,得到來一個C程序,以.i作為文件擴展名
  • 編輯階段。編譯器(ccl)干湖文本文件hello.i翻譯成文本文件hello.s,包含匯編語言程序。匯編語言程序中每條語句以一種標準文本格式確切地描述一條低級機器語言指令。匯編語言為不同高級語言的不同編譯器提供了通用輸出語言
  • 匯編階段。匯編器(as)將hello.s翻譯成機器語言指令,把這些指令打包成可重定位目標程序格式,將結果保存在目標文件hello.o中,hello.o是二進制文件,字節(jié)編碼是機器語言指令而不是字符,在文本編輯器打開hello.o文件,呈現亂碼
  • 鏈接階段。鏈接器(ld)并入標準庫函數printf,得到hello可執(zhí)行文件。可執(zhí)行文件加載到存儲器后,由系統負責執(zhí)行。

三、了解編譯系統如何工作的好處

  • 優(yōu)化程序性能。比如一個switch語句是不是比一系列if-then-else語句高效?一個函數調用代價多少?while循環(huán)比do循環(huán)更有效嗎?為什么兩個功能相近的循環(huán)的運行時間會有很大的差異?
  • 理解鏈接時出現錯誤。鏈接器報無法解析一個引用,是什么意思?靜態(tài)庫和動態(tài)庫的區(qū)別是什么?為什么有些鏈接錯誤直到運行時才出現?
  • 避免安全漏洞。緩沖區(qū)溢出錯誤造成大多數網絡和Internet服務器上的安全漏洞。

四、處理器讀并解釋在存儲器中的指令

(1) 系統硬件組成

為了理解運行hello程序發(fā)生了什么,需要理解典型系統的硬件組織。

CPI:中央處理器 ALU:算數/邏輯運算單元 PC:程序計數器 USB:通用串行總線

系統硬件組成.jpg

(a)總線

貫穿整個系統是一組電子管道,稱為總線,攜帶信息字節(jié)并在各個部件間傳遞。總線傳送定長字節(jié)塊

(b)I/O設備

I/O(輸入、輸出)設備是系統與外界的聯系通道。上述有2個I/O設備,用戶輸入的鍵盤和鼠標,作為用戶輸出的顯示器,用于長期存儲數據和程序的磁盤驅動器。最開始,可執(zhí)行程序hello放在磁盤上。

每個I/O設備通過控制器或適配器與I/O總線連接起來,控制器和適配器區(qū)別在于組成方式。控制器是I/O設備中或系統主印制電路板(通常為主板)上的芯片組,適配器一塊插在主板槽上的卡。功能是I/O總線和I/O設備之間傳遞信息。

(c)主存

臨時存儲設備,處理器執(zhí)行程序時,存放程序和程序處理的數據。主存是DRAM動態(tài)隨機存取存儲器芯片組成。邏輯上,存儲器由一個線性字節(jié)數組組成,每個字節(jié)有唯一的地址(數組索引),從零開始。一般來說,組成程序的每條機器指令由不定量字節(jié)構成。

(d)處理器

中央處理單元(CPU)簡稱處理器,執(zhí)行存儲在主存中指令的引擎。處理器核心是一個成為程序計數器(PC)的字長大小的存儲設備(或寄存器)。在任何一個時間節(jié)點,PC指向主存中的某條機器語言指令(內含地址)

從系統通電開始,直到系統斷電,處理器一直在重復執(zhí)行相同的基本任務:從程序計數器(PC)指向的儲存器處讀取指令,解釋指令中的位,執(zhí)行只來指示的簡單操作,然后更新程序計數器指向下一條指令,這條指令并不一定在存儲器中和剛剛執(zhí)行的指令相鄰。

CPU在指令的要求下可能執(zhí)行的操作

  • 加載:從主存拷貝一個字節(jié)或者一個字到寄存器,覆蓋寄存器原來的內容
  • 存儲:從寄存器拷貝一個字節(jié)或者一個字到主存著某個位置,覆蓋這個位置上原來的內容
  • 更新:拷貝兩個寄存器的內容到ALU,ALU將兩個字相加,并將課堂存放到一個寄存器中,覆蓋該寄存器中原來的位置
  • I/O讀:從一個I/O設備中拷貝一個字節(jié)或者一個字到寄存器
  • I/O寫:從一個寄存器拷貝一個字節(jié)或一個字到I/O設備
  • 轉移:從指令本身中抽取一個字,并將這個字拷貝到程序計數器(PC)中,覆蓋PC中原來的值

(2)執(zhí)行hello程序

shell程序執(zhí)行它的指令,當在鍵盤上輸入字符串./helo,shell程序逐一讀取字符到寄存器,再把它存放到存儲器中。

當我們岸上enter鍵,shell知道結束命令的輸入,shell執(zhí)行一系列指令,將hello目標文件中的代碼和數據從磁盤拷貝到主存,從而加載hello文件。

利用DMA(隨機存儲器存取)技術,數據可以不通過處理器直接從磁盤到主存

一旦hello目標文件中的代碼和數據加載到存儲器,處理器開始執(zhí)行hello程序的主程序中的機器語言指令。這些指令將hello,world\n串的字節(jié)從存儲器拷貝到寄存器文件,再從寄存器中文件拷貝到顯示設備,最終顯示在屏幕上。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容