天天看點

《程式是如何跑起來的》-----讀書筆記篇前言磁盤與記憶體的關系運作環境從源檔案到可執行檔案

程式是如何跑起來的

  • 前言
  • 磁盤與記憶體的關系
    • 虛拟記憶體
    • dll 檔案
  • 運作環境
  • 從源檔案到可執行檔案

前言

 不得不說,在這個假期借助“微信閱讀”讀到了很多有意義的書。不僅是思想境界上的,還有專業方向的。這一次我是在周三還是周四的一個活動中淘到了這本書,一開始大緻看了一下,還隻以為是的認為自己都大緻了解了(畢竟也是學了好幾年了嘛,得有點自信。)。在看了之後是真的贊歎,書是不嫌多的,總是很吸取到對自己有幫助的地方。

  這是一篇讀書筆記性質的部落格,有自己的了解,同時對于書中的内容也是進行選取的(重點選擇自己覺得之前沒有了解或沒有掌握到的知識)。

 這本書呢,正如其名,大體是介紹了程式是如何在計算機中運作的。首先呢,對于沒有學過太多有關方面知識(如計組、計網和編譯原理等)也是可以通過這本書了解到一個大體架構的(比如這其中涉及到了很多方面的知識,那麼在學到相關方面的課程的時候我們就大緻明白了這個課程與其餘知識的聯系,能讓我們能更好地對知識進行融會貫通);如果是學到了相關方面的知識,那麼我認為較大的好處是一方面可以對我們所學的知識有一個新的認知與鞏固(了解到在真實情況下所學的知識是如何使用到的),另一方面則是能查漏補缺将知識體系補充完整。

磁盤與記憶體的關系

在現如今的計算機體系中,程式必須要讀到記憶體中才是可以正常運作的。而這就使得磁盤和記憶體之間就存在着很多巧妙的設計。

《程式是如何跑起來的》-----讀書筆記篇前言磁盤與記憶體的關系運作環境從源檔案到可執行檔案

虛拟記憶體

虛拟記憶體指的是将磁盤的一部分作為假象的記憶體來使用。

  通過借助虛拟記憶體,在記憶體不足的時候也可以運作程式。

 由于CPU隻能執行記憶體中的程式。虛拟記憶體雖然說是将一部分磁盤當作記憶體來使用,但實際運作部分的程式是必須在記憶體中的。那麼我們可以想到,我們會将程式分成很多部分使得記憶體能一次性容納在運作的部分。 在很多地方,将磁盤上虛拟記憶體的内容轉移到實際記憶體中的操作稱之為 ----- 置換。

 現如今,虛拟記憶體主流的方式分為兩種:分頁式和分段式。在Windows中采用的是分頁式的手段。該方式指的是在不影響程式構造的基礎上,将程式按照一定大小的頁進行分割,并以頁為機關在記憶體和磁盤間進行置換。 如下圖

《程式是如何跑起來的》-----讀書筆記篇前言磁盤與記憶體的關系運作環境從源檔案到可執行檔案

 為了實作虛拟記憶體的功能,Windows在磁盤上提供了虛拟記憶體使用的檔案(頁檔案)。該檔案由Windows自動做成和管理。檔案大小也就是虛拟記憶體的大小。我們可以通過Windows的控制台檢視或變更目前虛拟記憶體的設定。如下圖

《程式是如何跑起來的》-----讀書筆記篇前言磁盤與記憶體的關系運作環境從源檔案到可執行檔案

dll 檔案

DLL(dynamic link library)檔案,是在程式運作的時候可以動态加載library(函數和資料的集合)的檔案。

 多個應用可以共有一個DLL檔案。而通過共有同一個DLL檔案可以達到節約記憶體的效果

 Windows的作業系統本身也是一個DLL檔案的集合體。除了利用多個DLL檔案可以節約記憶體之外,使用DLL檔案可以在不變更EXE檔案的情況下,隻通過更新DLL檔案就可以更新了。

運作環境

在程式中是離不開所依賴的運作環境的。是以,出現了我們如今常見的虛拟環境和docker等手段來建構适合程式運作的環境。那麼程式的運作環境是什麼呢?其實大緻可以這麼說:運作環境 = 作業系統 + 硬體。也就是說,作業系統和硬體決定了程式的運作環境。

 首先呢,現如今的同一類型硬體是可以選擇安裝多種作業系統的。同時,CPU隻能解釋其自身固有的機器語言。也就是說不同的CPU能解釋的機器語言的種類也是不同的。我們都知道程式最終都是要編譯成為機器語言的,這樣才能被CPU所執行。是以可以這麼說,運作環境是為了使得程式最終編譯成的機器語言符合該計算機的CPU能執行的形式的這個目标。(如下圖)

《程式是如何跑起來的》-----讀書筆記篇前言磁盤與記憶體的關系運作環境從源檔案到可執行檔案

 同時,現如今的體系結構大部分是,程式操控硬體是通過作業系統來間接控制的。也就是說如果作業系統不同,應用程式向作業系統傳遞指令的途徑也會有所不同。也就是說,在同類型的作業系統下,不管硬體如何,API基本上是沒有差别的。(這也是使用作業系統的一個好處,對上層進行了透明操作)。因而,針對某特定作業系統的API所編寫的程式,在任何硬體都可以運作。當然,可以由于CPU種類的不同,在本地上邊的代碼(機器語言)是有所不同的。

  1. 那麼我如果想在Windows上運作Linux的程式的話什麼辦?一個方法就是利用虛拟機獲得其他作業系統環境。也就是說我們在Windows上配置好Linux的虛拟機,之後程式就能調用Linux上的API進而能運作了,同時該Linux虛拟機需要适配好該Windows的硬體配置。(因為這個Linux調用的是Windows上的硬體)。(這個技術目前大部分是使用docker來替代了)
  2. 還有一種方式是使用想Java虛拟機這樣的方式。我們的源代碼會統一先編譯為名為位元組代碼的程式。位元組代碼的運作環境就稱為Java虛拟機。Java虛拟機是一邊把Java位元組代碼逐一轉換成本地代碼一邊運作的。(最終還是要轉換成本地CPU能執行的本地代碼,不同的是這個任何交給了Java虛拟機來進行轉換----這也是Java運作較慢的主要原因)
    《程式是如何跑起來的》-----讀書筆記篇前言磁盤與記憶體的關系運作環境從源檔案到可執行檔案

從源檔案到可執行檔案

  1. 将多個目标檔案(通過對源檔案進行編譯才得到目标檔案)結合生成EXE的工具稱為連結器。通過編譯和連結之後才能得到EXE檔案。
  2. 把多個目标檔案收錄在一起的檔案稱為:庫檔案
  3. 僅包含Windows的DLL檔案中存儲的函數資訊的檔案稱為:導入庫。将導入庫資訊結合到EXE檔案中,這樣程式在運作時就可以利用DLL内的函數了。
  4. 連結器會從庫檔案中抽取除必要的目标檔案并将其結合到EXE檔案之中。此外,還存在一種程式運作時結合的DLL形式的庫檔案。

 Windows中的編譯及連結機制如下圖

《程式是如何跑起來的》-----讀書筆記篇前言磁盤與記憶體的關系運作環境從源檔案到可執行檔案

繼續閱讀