這一段時間比較忙,可是仍是抽空看看這本書,你們都推薦看。linux
今天看了第一章《計算機系統漫遊》,主要講的是程序在計算機中的運行原理,這一部分講的我大部分都知道。不過仍是有不少不太清楚或者理解不許確的地方獲得了澄清。程序員
程序先由程序員編輯建立並保存在硬盤上,源程序在機器上表現爲01組成的位序列,8個位一個字節,每一個字節表示一個文本字符,它是以ascii碼的形式表示的。只由ascii字符組成的文件叫作文本文件,全部其餘的叫作二進制文件。shell
爲了讓機器可以識別並運行程序,每條語句必須被轉爲低級機器語言指令,而後將指令按照可執行目標程序的格式打包,並以二進制磁盤文件的形式存放起來。以c程序爲例,轉換過程大體分爲預處理,編譯,彙編,連接四個步驟。下面進行詳細解釋。編程
預處理器根據以字符#開頭的命令修改原始的c程序,好比#include<stdio.h>告訴預處理器讀取系統頭文件stdio.h的內容,並把它直接插入程序文本中,將#define的變量替換等等,結果獲得了另外一個c程序,一般以.i做爲文件擴展名。服務器
編譯器將文本文件hello.i翻譯成hello.s,它包含了一個彙編語言程序。彙編語言程序中的每條語句都以一種標準的文本格式確切的描述一條低級機器語言指令。網絡
彙編器將彙編程序翻譯爲機器語言指令,把這些指令打包成可重定位目標程序(relocateble object program)的格式,並把結果保存在hello.o中。hello.o文件是二進制文件,由於他的字節編碼是機器語言指令而不是ascii碼。若是用文本編輯器打開hello.o會看到一堆亂碼。多線程
連接階段,好比hello中用到了printf函數,這是標準c庫的函數,存在於一個名爲printf.o的單獨編譯好的目標文件中,這個文件必須以某種方式合併到咱們編譯好的的目標文件中。連接器(ld)程序負責處理這種合併,結果獲得hello文件,它是可執行目標文件,能夠被加載到內存中,由系統執行。併發
轉換完成以後就是執行了。在unix系統中,shell是一個命令行解釋器,輸出一個提示符,等待用戶輸入而後執行命令。若是輸入的第一個單詞不是一個內置的shell命令,shell將其解釋爲可執行文件,好比輸入./hello,它將加載並運行這個文件。hello在屏幕上輸出信息,而後終止。shell輸出一個提示符,等待下一個輸入的命令行。具體的過程爲:初始時,shell執行它的指令,等待輸入。用戶輸入字符創「./hello」後,shell將字符逐一讀入寄存器,而後存放到存儲器中,敲回車鍵後,shell知道用戶結束命令輸入。而後shell執行一系列的指令來加載可執行的hello文件,將hello目標文件的代碼和數據從磁盤複製到主存,數據包含輸出的字符串"HELLO,WORLD\n"。一旦目標文件hello中的代碼和數據被加載到主存,處理器開始執行main的機器語言指令,將字符串從主存拷貝到寄存器,並輸出到屏幕上。編輯器
因爲涉及大量的主存,磁盤,寄存器通訊,故產生了cache等緩衝提升速度的設備,減小通訊阻塞。函數
爲了減小用戶的負擔,操做系統對計算機硬件資源進行了抽象,產生了進程,線程,虛擬地址等概念。進程是程序的一次執行,是操做系統分配資源的單位,多個進程是能夠併發執行的,併發執行實際上每一個時刻執行的仍是一個進程,只不過進程間切換的速度比較快,給人的感受是併發執行。操做系統爲每一個進程保存執行的狀態信息,稱爲上下文,包括pc和寄存器文件當前值,主存內容等等。切換進程時,發生上下文切換。一個進程中能夠有多個線程執行單元,每一個線程都運行在進程的上下文中,共享一樣的代碼和數據,因爲網絡服務器等應用對並行處理的需求愈來愈大,多線程模型也愈來愈重要。虛擬地址爲每一個進程提供了一個假象,即每一個進程都在獨佔主存,每一個進程看到的是一致的存儲器,稱爲虛擬地址空間。虛擬地址空間是由大量的準肯定義的區構成,linux從低地址到高地址依次爲:程序代碼和數據;堆;共享庫;棧;內核虛擬存儲器。
程序執行的大概知識就是這些。