一段程式從編譯到硬體再到執行的過程

2022-08-30 05:06:12 字數 2457 閱讀 2065

(以下內容還未整理好,謹慎**哈哈哈)

前言知識:

主儲存器:是整個儲存系統的核心,它用來存放計算機執行期間所需要的程式和資料,cpu可直接隨機地對它進行訪問。

(主存地讀寫操作是在控制器地控制下進行的,只有接收到來自控制器地讀寫命令或寫允許後,才能實現正確地讀寫操作)

cpu:是整個計算機地核心,是對指令流和資料流在時間上與空間上實施正確地控制。

(指令流:指的是cpu執行的指令序列;資料流:指的是根據指令操作要求依次訪問資料地序列)

若用計算機來解決某個問題,首先要為這個問題編制解題程式,而程式又是指令的有序集合。

按照「儲存程式」的概念,只要把程式裝入主儲存器後,即可由計算機自動的完成取指令和執行指令的任務。

(程式要執行,必須被cpu呼叫執行,而前提是程式裝入到主存中)

那麼,程式如何裝入主儲存器?

1.程式的裝入與鏈結

大致流程圖如下:

具體流程如下:

(1)編譯(一般來說高階語言的編譯要經過預處理、編譯和彙編這幾個過程)

使用者源程式(比如.c檔案)經過編譯生成目標模組(.obj 組合語言或機器語言)

預處理:

預編譯過程對源**做了如下的操作:

刪除所有的注釋資訊

刪除所有的 #define 並展開所有巨集定義

插入所有 #include 檔案注1的內容到原始檔中的對應位置,include過程是遞迴執行的

gcc可以使用如下命令對c語言進行預編譯並且把預編譯的結果輸出到hello.i檔案中

gcc -e hello.c -o hello.i

編譯:

編譯就是對預處理之後的檔案進行詞法分析、語法分析、語義分析、中間**生成並優化後生成相應的彙編檔案。我們使用如下命令來編譯預處理之後的檔案

gcc -s hello.i -o hello.s

或者我們也可以把預處理和編譯合為一步

gcc -s hello.c -o hello.s

具體講解一下編譯過程:(後續完成)

詞法分析:

語法分析:

語義分析:

中間**生成:

**優化與目標**生成:

彙編的目的是把彙編**轉化為機器指令,因為幾乎每一條彙編指令都對應著一條機器指令,所以彙編的過程相對而言非常的簡單。我們可以使用如下命令實現彙編

gcc -c hello.s -o hello.o

或者我們也可以直接把源**檔案編譯為目標檔案

gcc -c hello.c -o hello.o

彙編操作所生成的檔案叫做目標檔案(object file),目標檔案的結構與可執行檔案是一致的,它們之間只存在著一些細微的差異。目標檔案是無法被執行的,它還需要經過鏈結這一步操作,目標檔案被鏈結之後才可以產生可執行檔案。

(2)鏈結

(3)裝入

將裝入模組裝入記憶體實際實體地址空間,並修改程式中與位址有關的**。(這一過程叫做位址重定位)。

程式裝入記憶體,作業系統要為新裝入記憶體的作業分配必要的資源,並為它建立程序(申請空白的pcb、初始化程序描述資訊、為程序分配資源和儲存空間、將程序插入到就緒佇列中)

裝人記憶體這一塊涉及到作業系統中的儲存管理。(把程式裝入記憶體的哪個區域?連續區域還是離散區域?)

一般這裡我們會涉及到頁式儲存管理、段式儲存管理、段頁式儲存管理和虛擬儲存管理。

程式裝入之後,cpu怎麼控制指令的執行呢?

2.cpu對主存的基本操作

那麼問題來了,cpu起初的位址訊號**來的?

(i/o軟體將使用者編制的程式通過匯流排(現在一般為單匯流排結構:cpu、主存和i/o裝置都鏈結到同一組匯流排上,使得cpu在i/o裝置與主存交換資訊時仍可繼續處理其他任務)輸入資訊到主機(由cpu和主存構成)中在程式開始執行前,將程式指令序列的起始位址,即程式的第一條指令所在的記憶體單元位址送入pc,cpu按照 pc的指示從記憶體讀取第一條指令(取指))。

程式在編譯的目標**生成過程中,通過**生成演算法將中間**轉換為特定機器的機器語言。如:

所以,在記憶體中裝載的都是程式的相應指令。

3.cpu排程程序執行程式

模板方法模式,(獲取一段程式執行的時間)

需求 獲取一段程式執行的時間。原理 獲取程式開始和結束的時間並相減 即可。public static long currenttimemillis 與1970年1月1日的毫秒差。用法 long start system.currenttimemillis 語句.long end system.cur...

java Java計算一段程式的執行時間

long starttime system.nanotime 獲取開始時間 測試的程式 long endtime system.nanotime 獲取結束時間 system.out.println 執行時間是 starttime endtime ns 輸出執行時間long starttime sys...

如何計算一段程式的執行時間

在程式設計時,在一些對時間要求比較高的情況,我們希望知道程式的執行需要用多長時間。如何才能獲得程式的執行時間呢,下面我們就介紹一種方法。這種方法基於gettimeofday 函式來實現,我們先來看一下 include includevoid delay int main 這段 的作用是計算delay...