程式是怎樣跑起來的

Locho發表於2024-11-10

總結自書籍:https://weread.qq.com/web/reader/94332ce0813ab7cc8g016ad1#outline?noScroll=1

計算機的組成:運算器、控制器、儲存器、輸入裝置、輸出裝置

  • 計算機內部都是由積體電路構成的,CPU和記憶體本質上都是積體電路,積體電路是由大量電晶體構成的電子部件
    • 積體電路的所有引腳都有0V或5V兩種狀態,因此計算機使用二進位制來處理資訊
    • CPU組成:暫存器、控制器、運算器、時鐘(之間透過電訊號相互連通)
    • CPU由不同功能的暫存器構成:程式計數器、累加器、標誌暫存器、指令暫存器、棧暫存器
    • 暫存器的本質是積體電路,暫存器的位數即資料引腳的個數,即能存放資料的bite數
    • 32位CPU指CPU的暫存器長度為32位元bite(1 bite = 1 位二進位制數)
  • 記憶體內部有很多能儲存8bite(1位元組)資料的容器,每個位元組都分配了一個地址,透過地址可讀寫記憶體中的指令和資料;記憶體透過控制電路與CPU相連
    • 假設要向下圖這塊記憶體晶片中寫入1位元組的資料,需要先給VCC接上 + 5V電源,給GND接上0V電源,然後透過A0~A9的地址訊號指定資料的儲存位置,將要寫入的資料值輸入資料訊號D0~D7,最後將WR訊號設定為1。這樣,資料就寫入了記憶體晶片​。當需要讀取資料時,我們需要透過地址訊號A0~A9指定資料儲存位置,將RD訊號設定為1,這時,指定地址中儲存的資料就會透過D0~D7的資料訊號引腳輸出

CPU可以直接解釋執行的只有機器語言,高階程式語言都需要編譯成機器語言,然後透過連結生成可執行的EXE檔案才能執行

  • 編譯:編譯的過程由編譯器完成,編譯器是將高階語言翻譯為機器語言的一種程式(在程式執行時對原始碼進行逐行翻譯的是直譯器
    • 程式是指示計算機完成一件事的指令和資料的集合
    • 機器語言由0、1組成,其本質是電訊號
      • 將機器語言的每種電訊號功能用英文單詞或其縮寫(即助記符)表示即為組合語言,組合語言可以透過“彙編”轉換為機器語言,機器語言可以透過“反彙編”轉換為組合語言
  • 連結:編譯生成的包含本機程式碼的目標檔案是不完整的,因為程式呼叫的函式的實際內容並非都在原始碼中(比如呼叫的外部函式),需要將所呼叫函式編譯生成的目標檔案連結在一起生成一個EXE檔案,這個將多個目標檔案拼接在一起的過程成為連結,完成這一操作的程式成為連結器
    • 啟動程式碼:需要連結在所有程式的開頭
    • 庫檔案:由多個目標檔案打包而成,在連結時指定庫檔案,連結器就可以從中提取所需的目標檔案,並將其與其他目標檔案一起連結生成EXE檔案
      • DLL:動態連結庫,在程式執行時才進行連結特殊庫檔案
      • 靜態連結庫:包含目標檔案本身,可以直接連結到EXE檔案的庫檔案
  • 執行:EXE檔案作為一個獨立的檔案儲存在硬碟中,當我們在資源管理器中雙擊EXE檔案時,EXE檔案中的內容會被載入到記憶體並執行
    • EXE檔案的內容分為重定位資訊、變數取、函式區。在EXE檔案中,變數和函式被分配的記憶體地址都是虛擬的,在程式執行時,這些虛擬的記憶體地址會轉換成實際的記憶體地址,連結器會在EXE檔案開頭記錄需要進行記憶體地址轉換的各個位置,這些資訊被稱為重定位資訊,即變數和函式的相對地址。在原始碼中,變數和函式都是分散在各個位置的,但在連結後的EXE檔案中,變數和函式會被集中起來分成兩組連續排列。於是,每個變數的記憶體地址就可以表示為該變數相對於變數區起始位置的偏移量,每個函式的記憶體地址也可以表示為該函式相對於函式區起始位置的偏移量。每個區的基地址是在程式執行時確定的
    • 記憶體中的程式由變數空間、函式空間、棧空間、堆空間4個區域組成。在載入程式的記憶體空間中,還會生成,棧用來存放函式臨時使用的區域性變數和呼叫函式時傳遞的引數,堆在程式執行時存放任意資料
      • 棧資料的存放和丟棄由編譯器自動生成的程式碼來完成
      • 記憶體中的對空間需要程式設計師透過程式顯示分配和釋放
      • 記憶體洩漏:程式執行結束後,記憶體空間依舊處於佔用狀態
      • 垃圾收集(garbage collection):指將堆空間中已經不再需要的資料進行清理,從而釋放被佔用的記憶體空間

磁碟

  • 計算機中的儲存器包括記憶體和磁碟。
  • 扇區是磁碟在物理上可讀寫的最小單位,是磁碟在邏輯上的讀寫單位,簇是n個扇區,同一個簇中不能存放不同的檔案,否則無法刪除簇中的部分檔案,所以檔案都是佔用簇的整數倍
  • 儲存在磁碟中的程式需要先載入到記憶體才能執行,不能在磁碟上直接執行。這是因為CPU在對程式內容進行解釋和執行時,是透過其內部的程式計數器指定記憶體地址來讀取程式的,如下圖(CPU能夠直接讀取並執行磁碟上的程式,由於磁碟讀取速度慢,所以程式的執行速度也會很慢)

程式的執行環境

  • 執行環境=作業系統+硬體(處理器、記憶體等)
  • 作業系統:多個程式的集合體,在作業系統中執行的應用程式透過作業系統提供的函式來間接訪問硬體
    • 系統呼叫:應用程式呼叫作業系統提供的函式
  • 作業系統和高階程式語言對硬體進行了抽象化 —— 檔案實際上就是作業系統將磁碟空間抽象化之後的形態
  • Java編寫的語音編譯後生成的是位元組碼,位元組碼的執行環境稱為Java虛擬機器(Java Virtual Machine,Java VM),JVM會將Java位元組碼逐一轉換為本機程式碼(即機器語言的程式)
  • 雲端計算:透過網際網路來使用硬體、作業系統、應用程式等計算機及資源,可分為以下幾類
    • SaaS:Software as a Service,軟體即服務,提供應用程式
    • PaaS:Platform as a Service,平臺即服務,提供作業系統
    • IaaS:Infrastructure as a Service,基礎設施即服務,提供硬體
  • 中介軟體:介於作業系統和應用程式中間的軟體(比如資料庫),作業系統和中介軟體統稱為系統軟體
  • 識別外部裝置的三件套:I/O埠號、IRQ、DMA通道
    • 計算機主機上有用於連結外部裝置的介面,這些介面內部裝有轉換主機和外部裝置電訊號的晶片,即I/O控制器,I/O控制器中有用於臨時存放輸入輸出資料的儲存器,即,透過埠號可以區分不同埠,埠號也成為I/O地址
      • in指令和out指令透過埠號可以在指定埠和CPU之間輸入和輸出資料,這與透過記憶體地址來讀寫記憶體是一樣的
    • 中斷處理:Interrupt Request(IRQ)中斷請求是一種讓當前正在執行的程式暫停,轉而執行其他程式的機制,這被稱為中斷處理
      • 中斷控制器:用於將來自多個外部裝置的中斷請求依次交給CPU處理
    • DMA:Direct Memory Access,直接記憶體訪問。指外部裝置不經過CPU中轉,直接和記憶體進行資料傳輸,可以將大量資料快速傳輸到記憶體(透過CPU在外部裝置和記憶體間傳輸資料的方式成為PIO Programmed I/O)
  • 視訊記憶體:計算機中用於儲存要顯示的資訊的儲存器

對高階語言的具體實現

  • 函式呼叫:呼叫指令先將呼叫函式的下一條指令的地址儲存到棧內,然後將函式入口地址設定到程式計數器,函式體執行完後,會在最後執行返回指令,返回指令將儲存在棧中的地址設定到程式計數器中
  • 迴圈和條件判斷:設定程式計數器的值

陣列是所有資料結構的基礎

  • 陣列是使用記憶體的基礎,各種記憶體的使用方式都是基於陣列發展出來的
  • 棧、佇列:先宣告一個資料存放資料,然後編寫函式讀寫元素
  • 連結串列:對於陣列中的每個元素,不僅要儲存它的值,還要額外儲存其下一個元素的下標
  • 二叉樹:陣列中的每個元素儲存其本身的值+其左右元素的下標

相關文章