1. 程式人生 > 其它 >20191215李業達第一、二章讀書筆記

20191215李業達第一、二章讀書筆記

一、知識點總結:

第一章:引言

前言:

該章是本書的引言部分,講述了Unix的歷史,包括各種unix的版本,還介紹了Linux的開發及其各種發行版,列出了適用於Linux的各種硬體平臺以及虛擬機器,還解釋了Linux的啟動過程,描述了Unix/Linux檔案系統組織等,最後介紹了使用者管理和維護Linux系統需執行的一些系統管理任務。

學到了什麼?

  1. 在1.2中提出系統程式設計的作用:有效利用系統資源來開發應用軟體;為學生打下紮實的專業基礎,以便在多個領域繼續深造。

  2. 1.3中提出本書的目標,包括強化學生的程式設計背景知識,動態資料結構的應用等。

  3. 在1.5中提到了本書的獨特之處,在眾多的獨特之處中我發現本書著重介紹了程式設計實踐,提供了一系列的程式設計專案,來讓學生練習程式設計,親自上手。

  4. 第一章中的內容還是比較簡單的,大體介紹了一下這本書的內容,以及我們可以需要學到的東西,讓我們對這本書以及這門課有個大體的認識,為之後的學習鋪好路。

  5. 書中最後提到了虛擬機器上的linux,我就想到了大一時婁老師讓我們安的虛擬機器,還好我到現在還沒有刪,我便打算繼續使用我大一所一直使用的virtualbox,但在我想要重新繼續使用時我的virtualbox遇到了不可啟動的bug,使用了好多方法廢了很多時間最後才把問題解決掉,才可以繼續使用繼續課程的學習。

第二章 程式設計背景

前言:

本章主要講述了系統程式設計所需的背景資訊:介紹了基於GUI的文字編輯器,如vim、gedit和EMACS,尤其是vim,我們在大一用過,我覺得這個編輯器再重新上手相較來說比較容易;展示瞭如何在命令和GUI模式下使用EMACS編輯器來編輯、編譯和執行C語言程式;闡述了程式開發的步驟;詳細闡釋了函式呼叫慣例和執行時堆疊的使用;展示了C語言程式與彙編程式碼的連結;討論了GNU make工具,舉例說明如何編寫makefile;提到了如何使用GDB除錯工具除錯C語言程式;提到了高階程式設計技術,以及C語言中的結構和指標,從單根目錄節點開始,興成檔案系統樹。

學到了什麼?

  1. 書中介紹了三種文字編輯器:vim,gedit,emacs.其中vim我較為熟悉,也是因為在大一的課程中稍微的接觸使用過。

  2. 2.1.1著重介紹了vim這一編輯器,與其他大多數編輯器不同,vim有3種不同的操作模式,分別是命令模式:用於輸入命令。插入模式:用於輸入和編輯文字。末行模式:用於儲存檔案並退出。vim啟動時,處於預設的命令模式,在該模式下,大多數鍵表示特殊命令。移動游標的

    命令鍵示例如下:
    
  • h:將游標向左移動一個字元

  • l:將游標向右移動一個字元

  • j:將游標向下移動一行

  • k:將游標向上移動一行

  • 對於Gedit來說,gedit是 GNOME桌面環境預設的文字編輯器。它是 Ubuntu及其他使用 GNOME 的GUI使用者介面的 Linux的預設編輯器,包含用於編輯原始碼和結構化文字(如標記語言)的工具。

  • Emacs其是一款強大的文字編輯器,可在多個不同的平臺上執行。最受歡迎的 emacs版本是 GNU Emacs,可在大多數 Linux發行版中使用。上述的許多文字編輯器由於我大一使用過vim於是我決定繼續在我接下來的課程中使用vim。

  • 程式開發:步驟:(1).建立原始檔:使用文字編輯器建立一個或多個程式原始檔;(2).用gcc把原始檔轉換成二進位制可執行檔案;(3).完成gcc三個步驟

  • C語言程式變數:全域性變數、區域性變數、靜態變數、自動變數和暫存器變數:全域性變數在函式外定義。區域性變數在函式內定義。全域性變數具有唯一性,並且只有一個副本。靜態全域性變數僅對定義它們的檔案可見。非靜態全域性變數則對同一程式的所有檔案都可見。
    全域性變數可以初始化,也可以不初始化。初始化的全域性變數在編譯時賦值。未初始化的全域性變數在程式執行開始時清零。區域性變數只對定義它們的函式可見。預設情況下,區域性變數是自動變數,它們在函式呼叫時出現,按邏輯在函式退出時消失。對於暫存器變數,編譯器試圖把它們分配在CPU暫存器中。由於自動區域性變數在函式呼叫前沒有分配記憶體空間,因此在編譯時不能初始化。靜態區域性變數具有永久性和唯一性,可以初始化。

  • 建立二進位制可執行檔案的方式有:靜態連結和動態連結。其中動態連結的優點是:可減小每個a.out檔案 的大小;許多執行程式可在記憶體中共享相同的庫函式;修改庫函式不需要重新編譯原始檔。

  • 大部分C編譯器和連結器可生成多種不同格式的可執行檔案:(1)二進位制可執行平面檔案;(2)a.out可執行檔案;(a.out檔案的內容包括檔案頭、程式碼段、資料段和符號表)(3)ELF可執行檔案。

  • 靜態與動態連結:建立二進位制可執行檔案的方式有兩種,分別是靜態連結動態連結。在使用靜態庫的靜態連結中,連結器將所有必要的庫函式程式碼和資料納a.out檔案中。這使得aout檔案完整、獨立,但通常非常大。在使用共享庫的動態連結中,庫函式未包含在a.out檔案中,但是對此類函式的呼叫以指令形式記錄在a.out檔案中。在執行動態連結的a.out檔案時,作業系統將a.out檔案和共享庫均載入到記憶體中,使載入的庫程式碼在執行期間可供a.out檔案訪問。

  1. 動態連結的主要優點是
  • 可減小每個aout檔案的大小

  • 許多執行程式可在記憶體中共享相同的庫函式。

  • 修改庫函式不需要重新編譯原始檔。

動態連結所用的庫稱為動態連結庫(DLL)。它們在 Linux中稱為共享庫(.s0檔案)。動
態載入(DL)庫是指僅按需載入的共享庫。動態載入庫可用作外掛和動態載入模組

  1. a.out檔案的內容
    為了簡便起見,我們首先討論傳統的a.out檔案。
    a.out檔案包括以下部分:
  • 檔案頭:檔案頭包含a.out檔案的載入資訊和大小,其中
  • tsize=程式碼段大小
  • dize=包含初始化全域性變數和初始化靜態區域性變數的資料段的大小
  • bsize=包含未初始化全域性變數和未初始化靜態區域性變數的bs段的大小
  • total size=載入的a.out檔案的總大小

(1). 程式碼段:也稱為正文段,其包含程式的可執行程式碼。程式碼段從標準C啟動程式碼開始,該程式碼呼叫main()函式。

(2). 資料段:資料段包含初始化全域性變數和初始化靜態資料:

(3). 符號表:可選,僅為執行除錯所需。

最有收穫的內容:

看完第一章與第二章的內容我對於程式的執行與停止這一過程較為感興趣,並且有一定的收穫,因為這一部分與我的日常學習聯絡最為緊密,我需要了解我的程式如何執行與停止。

1.程式執行過程****

在類Unix作業系統中,在sh命令列執行a.out檔案,以標記字串作為命令列引數。為執行命令,sh建立一個子程序並等待該子程序終止。子程序執行時,sh使用a.out檔案,按照以下步驟建立新的執行映像。

(1)讀取aout檔案頭,以確定所需的總記憶體大小,包括堆疊空間大小:

Totalsize=brk stacksize

其中,堆疊大小通常是作業系統核心為待啟動程式選擇的預設值。無法知道一個程式究竟需要多大的堆疊空間。作業系統核心通常使用待啟動程式的預設初始堆疊大小,並試著處理隨後在執行期間可能出現的堆疊溢位問題。

(2)sh從總大小中分配一個記憶體區給執行映像。從概念上講,我們可假設分配的記憶體區是一個單獨的連續記憶體。sh將a.out檔案的程式碼段和資料段載入到記憶體區中,堆疊區位於高位地址端。sh將bss段清除為0,使得所有未初始化全域性變數和未初始化靜態區域性變數以初始值0開始。執行期間,堆疊向下朝低位地址延伸。

(3)然後,sh放棄舊映像,開始執行新映像,

2.程式終止

可通過兩種可能的方法終止正在執行a.out的程序。

(1)正常終止:如果程式執行成功,main()最終會返回到crt0.0,呼叫庫函式exit(0)來

終止程序。首先, exit(value))函式會執行一些清理工作,如重新整理 stdout、關閉/0流等。然

後,它發出一個 exit(value))系統呼叫,使進入作業系統核心的程序終止。退出值0通常表

示正常終止。如果需要,程序可直接呼叫 I exit(value),不必返回到crt0.0。再直接一點,進

程可能會發出 exit( value))系統呼叫以立即終止,不必先進行清理工作。當核心中的某個進

程終止時,它會在程序結構體中將 f exit(value))系統用值記錄為退出狀態,通知它的父進

程並使該程序成為殭屍程序。父程序可通過系統呼叫

pid wait(int * atatus)i

找到殭屍子程序,獲得其pid和退出狀態,它還會清空殭屍子程序的結構體,使該結構體可

被另一個程序重新使用。

(2)異常終止:在執行a.out時,程序可能會遇到錯誤,如無效地址、非法指令、越權

等,這些錯誤會被CPU識別為異常。當某程序遇到異常時,它會陷入作業系統核心。核心

的陷入處理程式將陷入錯誤型別轉換為一個幻數,稱為訊號,將訊號傳遞給程序,使程序終

止。在這種情況下,殭屍程序的退出狀態就是訊號數值,我們可以說該程序異常終止了。除

了錯誤導致的陷入,訊號也可能來自硬體或其他程。例如,按下“Ctrl+C”組合鍵會產生

硬體中斷,它會向該終端上的所有程序傳送數字2的訊號 SIGINT,使程序終止。或者,用

戶可以使用命令

kill -s signal number pid

signal number 1 to 31

向通過pid識別的目標程序傳送訊號。對於大多數訊號數值,程序的預設操作是終止。

問題與解決思路

我在準備將書上的程式碼敲入我的虛擬機器時遇到了虛擬機器無法啟動這一問題:

查閱資料

我選擇在網上查閱資料,查詢到了包括重新安裝,更改登錄檔,重新啟動服務等方法,但沒有一個是奏效的,哪怕我將同學的檔案拷來電腦上也無法解決該問題

依舊無法啟動。

3.自我總結

我在接下來的時間中還需要用更多的時間來把這個問題解決掉,這一問題嚴重的影響了我的學習,網上的辦法無一例外都無法解決,我需要找到更多辦法,這一問題的解決過程我還會在我的部落格園持續更新,直到解決。