一、CPU如何執行程序?
提綱
- 圖靈機工作方式
- 馮諾依曼模型
- 線路位寬CPU位寬
- 程序執行基本過程
- 執行具體過程
1. 圖靈機工作方式
圖靈機可以視作“一臺帶規則的自動草稿機”
圖靈機基本組成:
-
紙帶(內存):連續格子組成,每個格子寫入字符,紙帶好比內存,格子上的字符好比內存中的程序與數據;
-
讀寫頭:一支筆,能讀格子、改符號、左右移動。
-
狀態表:一本規則手冊,
-
控制器:負責對照規則表,自動執行上面操作。
-
工作過程:循環 “看→改→移→換狀態”
從 初始狀態 開始,重復以下步驟: -
① 讀:讀寫頭看當前格子的符號(比如 1);
-
② 查規則:根據當前狀態和符號,查狀態表,得到三個指令(改什么符號、往哪移、變啥狀態);
-
③
改 + 移:按指令改符號、移動讀寫頭; ④ 換狀態:切換到新狀態,回到步驟①,直到碰到 終止狀態 停下。
總的來說,圖靈機計算1+2的過程。圖靈機的主要功能就是讀取紙帶格子中的內容,交給控制單元識別字符是數字還是運算符,如果是數字存入狀態器,如果是運算符,則通知運算符單元讀取狀態中的數值進行計算,計算結果最終返回給讀寫頭,讀寫頭將結果寫入到紙袋的格子中。
2.馮諾依曼模型
1945年馮諾依曼遵循圖靈機設計,提出用電子元件構建計算機,并約定二進制進行計算和存儲。
馮諾依曼計算機基本結構有5個重要部分,運算器、控制器、存儲器、輸入設備和輸出設備。
運算器、控制器是在中央處理器中,存儲器就是內存,輸入輸出都是計算機外設,比如鼠標鍵盤是輸入設備,顯示器是輸出設備。
內存
計算機的程序和數據都存儲在內存中,存儲基本單位是字節(byte),1字節等于8位(8 bit)。每個字節對應一個內存地址。
存儲區域線性,指內存地址從0開始編號,自增排序,類似數組,最后一個地址為內存總字節數-1,因此內存讀寫任何一個數據的速度是一樣的。
中央處理器
中央處理器即CPU,32位CPU和64位CPU區別在于一次能計算多少字節數據:
- 32位CPU一次可以計算4字節;
- 64位CPU一次可以計算8字節;
32 位和 64 位,通常稱為 CPU 的位寬,代表的是 CPU 一次可以計算(運算)的數據量。
32 位和 64 位,通常稱為 CPU 的位寬,代表的是 CPU 一次可以計算(運算)的數據量。如果是 8 位的 CPU,那么一次只能計算 1 個字節(0-255)范圍內的數值,這樣就無法完成一次10000 * 500
總線
輸入輸出
Linux內核 vs Windows內核
內核
內核是什么?[應用與硬件設備交互的中間橋梁]
計算機由外部硬件設備構成,CPU、內存、硬盤等,如果每個應用都要和這些硬件對接通信協議就太麻煩!所以需要一個“中間人”,統一對接應用和計算機硬件。內核就是應用連接硬件設備的橋梁,應用只關心如何與內核交互,不用關心硬件細節!
內核有什么能力?
- 進程調度:
- 管理進程線程,決定哪個進程線程用CPU;
- 內存管理:
- 管理內存,決定內存分配與回收;
- 硬件通信:
- 管理硬件設備,為進程與硬件設備之間提供通信功能;
- 系統調用:
- 提供系統調用,如果應用程序需要運行更高權限的服務,就需要用到系統調用,是用戶程序與操作系統之間的接口;
內核如何工作?
內核權限高,可以直接控制CPU、內存、硬盤等硬件設備,而應用程序權限很小,因此操作系統把內存分為兩個區域:
- 內核空間:這個內存空間只有內核程序可以訪問。
- 用戶空間:這個內存空間專門給應用程序使用;
內核空間的代碼可以訪問所有內存空間,用戶空間的代碼只能訪問一個局部的內存空間。
因此,當程序使用用戶空間的時候,我們稱該程序在用戶態執行;程序使用內核空間時,程序在內核態運行。
應用程序如果需要進入內核空間,就需要系統調用實現:
系統調用與中斷:
正常情況下,內核程序執行在內核態,用戶程序執行在用戶態。當應用程序使用系統調用時,會產生一個中斷,發送中斷后,CPU會中斷當前執行中的用戶程序,轉而跳轉到中斷處理程序,也就是開始執行內核程序,內核程序處理完畢后,主動觸發中斷,把CPU執行權限交回用戶程序,回到用戶態繼續工作。
Linux的設計
Linux誕生于1991年,芬蘭小伙子C語言實現。
Linux設計理念:
- MultiTask,多任務;
- SMP,對稱多處理;
- ELF,可執行文件鏈接格式;
- Monolithic Kernel,宏內核;
MultiTask
Linux是個多任務操作系統,可以有多個任務同時(并發 / 并行)進行。
- 并發:單核CPU,輪流處理多個任務,每個任務處理一段時間就切換執行另一個任務,宏觀上同時處理多個任務;
- 并行:多核CPU,多個CPU核心真正同時處理多個任務;
SMP
Linux具有對稱多處理特性,代表每個CPU地位相等,具體的:
- 資源使用權限相同;
- 多CPU共享同個內存;
- 每個CPU都可以訪問完整的內存和硬件資源;
不存在Linux某個程序單獨服務某個應用或者內核程序,每個程序都可以被分配到任意一個CPU執行。
ELF
ELF(Executable and Linkable Format,可執行與可鏈接格式)是 Linux 系統中最常用的二進制文件格式,簡單說,它就像一個 “統一的包裝盒”,能裝下程序編譯、鏈接、運行過程中需要的各種二進制數據(比如代碼、數據、符號等),并且讓系統和工具(編譯器、鏈接器、操作系統)能 “看懂” 里面的內容。
它的核心特性可以通俗理解為:
- “一包多用” 的通用性
- 同一個格式能裝多種類型的文件:比如編譯中間產生的目標文件(.o)、最終能直接運行的可執行文件、共享庫(.so,類似 Windows 的.dll),甚至程序崩潰時的核心轉儲文件(core dump)。不用為不同類型的二進制文件設計多種格式,簡化了系統處理邏輯。
- “結構化打包” 的靈活性
ELF 文件內部像 “分層抽屜”:
- 最外層有個 “標簽頁”(ELF頭部),記錄文件類型(是可執行文件還是庫)、適配的 CPU 架構(x86/ARM 等)、入口地址(程序從哪開始跑)等關鍵信息。
- 里面的內容按 “用途” 分區域放:比如
“代碼區”(.text,存程序指令)、“數據區”(.data,存初始化的變量)、“符號表”(.symtab,存函數 /
變量的名字和地址)等。 這些區域在 “打包”(鏈接階段)時按 “節(Section)” 劃分,在 “拆包運行”(加載到內存)時按
“段(Segment)” 劃分,既方便編譯器鏈接,又方便操作系統加載到內存。
- “跨設備兼容” 與 “可擴展”
它不挑 CPU 架構,只要在 “標簽頁” 里注明適配的架構(比如 x86 或 ARM),不同設備都能識別。而且如果以后有新需求(比如加新類型的數據),可以在 “抽屜” 里加新的區域,不影響原有結構,擴展性很強。 - “按需加載” 的動態鏈接支持
比如我們寫程序時用了系統庫(如 printf 函數),ELF 能讓程序不把庫代碼 “打包”
進自己的文件里,而是在運行時通過 “動態鏈接器”(類似 “快遞員”)臨時加載系統里的共享庫(.so)。這樣既節省內存(多個程序共用一個庫),又方便庫更新(改庫不用重新編譯所有程序)。 - “清晰的符號管理” 程序里的函數名、變量名(比如 “add 函數”“count 變量”),在 ELF 里會被記錄在 “符號表” 中,像 “通訊錄” 一樣,告訴編譯器 / 鏈接器 “這個名字對應哪個地址”,確保程序運行時能正確找到要用的函數或變量。
總之,ELF 的核心是 “統一、靈活、兼容”,讓 Linux 系統里的二進制文件從編譯到運行的全流程都能被高效處理,是 Linux 程序能正常工作的 “幕后功臣”。
ELF 文件有兩種索引,Program header table 中記錄了運行時所需要的段,而Section header table 記錄了二進制文件中的各個段的首地址。
ELF如何生成?
我們編寫的代碼,首先通過編譯器編譯成匯編代碼,接著通過匯編器編程目標代碼,也就是目標文件,最后通過鏈接器把多個目標文件以及調用的各自函數庫鏈接起來,形成可執行文件即ELF。
ELF如何被執行呢?
執行ELF文件時,會通過裝載器把ELF文件裝載在內存中,CPU讀取內存中的指令和數據,程序就被執行起來了。
Monolithic Kernel
Monolithic Kernel 即宏內核,是操作系統內核一種經典架構:把操作系統所有核心功能(比如進程管理、內存分配、文件系統、設備驅動、中斷處理等)都打包在一個單一的內核程序里,并且認為它們都運行在最高權限的“內核態”。
宏內核的核心特征:
- “大一統”結構:不像微內核(Microkernel)那樣把功能拆成多個獨立模塊,宏內核里所有關鍵組件都 “擠” 在同一個內存空間里,彼此直接通信(比如函數調用),不需要復雜的跨進程交互。
- 效率優先:因為組件間通信直接,沒有額外的權限切換或消息傳遞開銷,所以性能通常比較高(比如進程調度、內存訪問更快)。
- 依賴內核態特權:所有核心功能都運行在 “內核態”(操作系統的最高權限模式),能直接訪問硬件資源,省去了用戶態與內核態切換的成本。
優缺點:
- 優點:性能好,響應快,適合對效率敏感的場景(比如服務器、桌面系統)。
- 缺點:內核體積大、結構復雜,修改或維護某個功能(比如加一個新設備驅動)可能需要重新編譯整個內核;而且一個組件出問題(比如驅動崩潰)可能導致整個內核崩潰。
與之相對的是微內核(Microkernel)
核心思路是極簡核心+外部服務:
只把操作系統最底層、最必要的功能(進程調度、內存基礎管理、進程之間消息傳遞)放進內核態,其他功能(文件系統、設備驅動、網絡協議)都做成獨立的服務進程,跑在用戶態。
混合內核(Hybrid Kernel)
核心思路是“取兩者之長”:
保留微內核的精簡核心框架,但是把一些常用的關鍵服務(文件系統、設備驅動)挪到內核態,減少消息傳遞的開銷。
既不會像微內核那樣,所有非核心功能都在用戶態,可以避免性能損失。也不會像宏內核那樣所有功能都擠在核內,保證了一定模塊化。
- 優點:平衡了模塊化設計與性能需求;
Windows設計
當今Windows7/10使用的內核叫做Windows NT,全稱New Technology。
與Linux異同點:
- 相同:
- 多任務
- 對稱多處理
- 不同:
- 混合型內核:
- 可執行文件:PE,可移植執行文件
總結
內核架構:
- 宏內核:包含多個模塊,整個像一個完整的程序都運行在內核態。
- 微內核:有一個最小版本的內核只負責最重要的功能,一些模塊和服務則有用戶態管理。
- 混合內核:是宏內核和微內核的結合,內核中抽象出了微內核的概念,也就是內核中有一個小型的內核,其他模塊在這個基礎上搭建,整個內核就是個完整的程序。
Linux采用了宏內核設計,Windows采用了混合內核設計。
兩個操作系統的可執行文件是最大差異,Linux是ELF,Windows是PE.