CSAPP-一-計算機系統漫遊

title: CSAPP(一)–計算機系統漫遊
author: Qian Jipeng
tags:

  • 計算機系統
  • 動態鏈接
  • 靜態鏈接
  • 編譯系統
    categories:
  • 計算機系統
    date: 2019-08-29 11:20:00

計算機系統學習

狂補知識ing…

計算機系統

計算機系統是由計算機硬件和系統軟件組成的,它們共同工作來與進行應用程序。接下來,我會以hello.c爲例,進行一些零散的總結。

#include <stdio.h>
int main() {
	printf("Hello World!\n");
    return 0;
}

信息

信息就是位+上下文,我們的hello.c文件叫源文件、源程序,實際上就是一個由值0和1組成的位序列,叫比特(bit),8個位被組織成一組,成爲一個字節(byte),每個字節表示程序中的某些文本字符,現在大部分的計算機都使用ANSII標準來存儲字符,每個字符都對應唯一的單字節大小的整數值,叫ANSII值

編譯系統

目前的C、C++、Pascal等都是高級語言,彙編語言也是一些彙編指令,只有最低級的機器指令(0、1序列)才能夠被計算機直接“識別”,所以說,要想運行一串高級語言代碼,必須要有一樣東西,把這些高級語言代碼轉換爲計算機能夠直接識別的機器指令,這就是編譯器的作用。
一個計算機編譯系統,由四部分組成:

  • 預處理器(ccp)
  • 編譯器(ccl)
  • 彙編器(as)
  • 鏈接器(ld)
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DlLXlS0E-1570954478966)(http://px1awapyv.bkt.clouddn.com/55.png)]
    相應的,一個程序的編譯過程,也分爲四個階段:
  • 預處理階段
    預處理器會掃描源文件,定位到以"#"開頭的內容,根據這個內容,修改源文件的內容,比如說前面#include <stdio.h>,這時候,我就要找到stdio.h這個頭文件,把這個頭文件的內容直接插入到hello.c源文件中(至於具體在哪個位置,我們不知道)
    ,生成新的源文件hello.i,通常以**.i**作爲文件擴展名。
  • 編譯階段
    編譯器會將文本文件hello.i翻譯成文本文件hello.s,它包含了一個彙編語言程序,。即將高級語言翻譯成彙編語言。的彙編程序可以爲不同的高級語言和不同的編譯器提供通用的輸出語言。
    gcc -S hello.s hello.c
  • 彙編階段
    彙編器將彙編語言翻譯成機器語言指令,把這些指令打包成一種叫做可重定位目標程序的格式,將結果放在hello.o這個二進制文件中。
    gcc -c hello.o hello.c
  • 鏈接階段
    我們的hell.o調用了stdio的printf()函數,它是C語言的一個標準庫函數,位於printf.o這個獨立的預編譯好了的目標文件中,必須要加入我們的hello.o文件中,程序才能夠正常運行。鏈接器就是做這個工作的,將printf.o文件與hello.o文件鏈接,得到hello可執行目標文件,當然,也是二進制文件。這個可執行目標文件可以加載到內存中,被計算機所執行。
    gcc -o hello hello.c 這樣的命令會生成可執行文件hello,一般沒有後綴。

瞭解編譯系統的工作流程

帶來的好處:

  • 優化程序性能
    比如說,switch就會比if效率高嗎?while和for的效率問題,函數調用的開銷到底有多大,傳指針和傳值到底有什麼區別?
    這些目前我還不清楚、或者說不太清楚,所知道的也就是從書上、網上學來的。或許學了程序的編譯過程,就會明白了把。
  • 理解鏈接時的錯誤
    寫代碼時,經常會遇到鏈接錯誤,順帶提一下,動態鏈接靜態鏈接,待學習。

動態鏈接和靜態鏈接

1. 動態鏈接
  Windows: .lib文件
  Linux: .a文件
  函數庫的一份拷貝是可執行文件的物理組成部分,稱之爲靜態鏈接。靜態鏈接當鏈接程序時,需要使用的每個庫函數的一份拷貝被加入到可執行文件中。靜態鏈接使用靜態庫進行鏈接,生成的程序包含程序運行所需要的全部庫,可以直接運行,不過靜態鏈接生成的程序體積較大(即使是在靜態鏈接中,整個庫文件也並沒有全部裝入到可執行文件中,所裝入的只是需要的函數)。
2. 靜態鏈接
  Windows: .dll文件
  Linux: .so文件
  如果可執行文件只是包含了文件名,讓載入器在運行時能夠尋找程序所需要的函數庫,稱之爲動態鏈接。動態鏈接允許系統提供一個龐大的函數庫集合,可以提供許多有用的服務,程序在運行時尋找它們。動態鏈接使用動態鏈接庫進行鏈接,生成的程序在執行的時候需要加載所需的動態庫才能運行。動態鏈接生成的程序體積較小,但是必須依賴所需的動態庫,否則無法執行。
3. 細節
  gcc編譯器默認使用動態編譯,如果要指定靜態編譯,需要加上-static參數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章