(以下內容還未整理好,謹慎觀看哈哈哈)
前言知識:
主存儲器:是整個存儲系統的核心,它用來存放計算機運行期間所需要的程序和數據,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)鏈接
將編譯后形成的多個目標模塊以及它們所需要的庫函數鏈接在一起形成裝入模塊。(裝入模塊雖然具有統一的地址空間,但是它任是以“0”作為參考地址)
(3)裝入
將裝入模塊裝入內存實際物理地址空間,並修改程序中與地址有關的代碼。(這一過程叫做地址重定位)。
程序裝入內存,操作系統要為新裝入內存的作業分配必要的資源,並為它創建進程(申請空白的PCB、初始化進程描述信息、為進程分配資源和存儲空間、將進程插入到就緒隊列中)
裝人內存這一塊涉及到操作系統中的存儲管理。(把程序裝入內存的哪個區域?連續區域還是離散區域?)
一般這里我們會涉及到頁式存儲管理、段式存儲管理、段頁式存儲管理和虛擬存儲管理。
程序裝入之后,cpu怎么控制指令的執行呢?
2.CPU對主存的基本操作
CPU對主存進行讀寫操作時候,首先CPU在地址總線上給出地址信號,然后發出相應的讀或寫命令,並在數據總線上交換信息。讀寫的基本操作如下:
那么問題來了,CPU起初的地址信號哪里來的?
(I/O軟件將用戶編制的程序通過總線(現在一般為單總線結構:CPU、主存和I/O設備都連結到同一組總線上,使得CPU在I/O設備與主存交換信息時仍可繼續處理其他任務)輸入信息到主機(由CPU和主存構成)中在程序開始執行前,將程序指令序列的起始地址,即程序的第一條指令所在的內存單元地址送入PC,CPU按照 PC的指示從內存讀取第一條指令(取指))。
程序在編譯的目標代碼生成過程中,通過代碼生成算法將中間代碼轉換為特定機器的機器語言。如:
所以,在內存中裝載的都是程序的相應指令。
3.CPU調度進程執行程序