基本微機設計
下圖給出了假想機的基本設計。中央處理單元(CPU)是進行算術和邏輯操作的部件,包含了有限數量的存儲位置——寄存器(register),一個高頻時鍾、一個控制單元和一個算術邏輯單元。
其中:
- 時鍾 (clock) 對 CPU 內部操作與系統其他組件進行同步。
- 控制單元 (control unit, CU) 協調參與機器指令執行的步驟序列。
- 算術邏輯單元 (arithmetic logic unit, ALU) 執行算術運算,如加法和減法,以及邏輯運算,如 AND(與)、OR(或)和 NOT(非)。
CPU 通過主板上 CPU 插座的引腳與計算機其他部分相連。大部分引腳連接的是數據總線、控制總線和地址總線。
內存存儲單元 (memory storage unit) 用於在程序運行時保存指令與數據。它接受來自 CPU 的數據請求,將數據從隨機存儲器 (RAM) 傳輸到 CPU,並從 CPU 傳輸到內存。
由於所有的數據處理都在 CPU 內進行,因此保存在內存中的程序在執行前需要被復制到 CPU 中。程序指令在復制到 CPU 時,可以一次復制一條,也可以一次復制多條。
總線 (bus) 是一組並行線,用於將數據從計算機一個部分傳送到另一個部分。一個計算機系統通常包含四類總線:數據類、I/O 類、控制類和地址類。
數據總線 (data bus) 在 CPU 和內存之間傳輸指令和數據。I/O 總線在 CPU 和系統輸入 / 輸出設備之間傳輸數據。控制總線 (control bus) 用二進制信號對所有連接在系統總線上設備的行為進行同步。當前執行指令在 CPU 和內存之間傳輸數據時,地址總線 (address bus) 用於保持指令和數據的地址。
時鍾與 CPU 和系統總線相關的每一個操作都是由一個恆定速率的內部時鍾脈沖來進行同步。機器指令的基本時間單位是機器周期 (machine cycle) 或時鍾周期 (clock cycle)。
一個時鍾周期的時長是一個完整時鍾脈沖所需要的時間。下圖中,一個時鍾周期被描繪為兩個相鄰下降沿之間的時間:

時鍾周期持續時間用時鍾速度的倒數來計算,而時鍾速度則用每秒振盪數來衡量。例如,一個每秒振盪 10 億次 (1GHz) 的時鍾,其時鍾周期為 10 億分之 1 秒 (1 納秒 )。
執行一條機器指令最少需要 1 個時鍾周期,有幾個需要的時鍾則超過了 50 個(比如 8088 處理器中的乘法指令)。由於在 CPU、系統總線和內存電路之間存在速度差異,因此,需要訪問內存的指令常常需要空時鍾周期,也被稱為等待狀態 (wait states)。
指令執行周期
一條機器指令不會神奇地一下就執行完成。CPU 在執行一條機器指令時,需要經過一系列預先定義好的步驟,這些步驟被稱為指令執行周期 (instruction execution cycle)。假設現在指令指針寄存器中已經有了想要執行指令的地址,下面就是執行步驟:
1) CPU 從被稱為指令隊列 (instruction queue) 的內存區域取得指令,之后立即增加指令指針的值。
2) CPU 對指令的二進制位模式進行譯碼。這種位模式可能會表示該指令有操作數(輸入值)。
3) 如果有操作數,CPU 就從寄存器和內存中取得操作數。有時,這步還包括了地址計算。
4) 使用步驟 3 得到的操作數,CPU 執行該指令。同時更新部分狀態標志位,如零標志 (Zero)、進位標志 (Carry) 和溢出標志 (Overflow)。
5) 如果輸出操作數也是該指令的一部分,則 CPU 還需要存放其執行結果。
通常將上述聽起來很復雜的過程簡化為三個步驟:取指 (Fetch)、譯碼 (Decode) 和執行 (Execute)。操作數 (operand) 是指操作過程中輸入或輸出的值。例如,表達式 Z=X+Y 有兩個輸入操作數 (X 和 Y),—個輸岀操作數 (Z)。
下圖是一個典型 CPU 中的數據流框圖。該圖表現了在指令執行周期中相互交互部件之間的關系。在從內存讀取程序指令之前,將其地址放到地址總線上。然后,內存控制器將所需代碼送到數據總線上,存入代碼高速緩存 (code cache)。指令指針的值決定下一條將要執行的指令。指令由指令譯碼器分析,並產生相應的數值信號送往控制單元,其協調 ALU 和浮點單元。雖然圖中沒有畫出控制總線,但是其上傳輸的信號用系統時鍾協調不同 CPU 部件之間的數據傳輸。

讀取內存
作為一個常見現象,計算機從內存讀取數據比從內部寄存器讀取速度要慢很多。這是因為從內存讀取一個值,需要經過下述步驟:- 將想要讀取的值的地址放到地址總線上。
- 設置處理器 RD(讀取)引腳(改變 RD 的值)。
- 等待一個時鍾周期給存儲器芯片進行響應。
- 將數據從數據總線復制到目標操作數。
上述每一步常常只需要一個時鍾周期,時鍾周期是基於處理器內固定速率時鍾節拍的一種時間測量方法。計算機的 CPU 通常是用其時鍾速率來描述。例如,速率為 1.2GHz 意味着時鍾節拍或振盪為每秒 12 億次。
因此,考慮到每個時鍾周期僅為 1/1 200 000 000 秒,4 個時鍾周期也是非常快的。但是,與 CPU 寄存器相比,這個速度還是慢了,因為訪問寄存器一般只需要 1 個時鍾周期。
幸運的是,CPU 設計者很早之前就已經指出,因為絕大多數程序都需要訪問變量,計算機內存成為了速度瓶頸。他們想出了一個聰明的方法來減少讀寫內存的時間一一將大部分近期使用過的指令和數據存放在高速存儲器 cache 中。
其思想是,程序更可能希望反復訪問相同的內存和指令,因此,cache 保存這些值就能使它們能被快速訪問到。此外,當 CPU 開始執行一個程序時,它會預先將后續(比如)一千條指令加載到 cache 中,這個行為是基於這樣一種假設,即這些指令很快就會被用到。
如果這種情況重復發生在一個代碼塊中,則 cache 中就會有相同的指令。當處理器能夠在 cache 存儲器中發現想要的數據,則稱為 cache 命中 (cache hit)。反之,如果 CPU 在 cache 中沒有找到數據,則稱為 cache 未命中 (cache miss)。
x86 系列中的 cache 存儲器有兩種類型:一級 cache(或主 cache)位於 CPU 上;二級 cache (或次 cache)速度略慢,通過高速數據總線與 CPU 相連。這兩種 cache 以最佳方式一 起工作。
還有一個原因使得 cache 存儲器比傳統 RAM 速度快,cache 存儲器是由一種被稱為靜態 RAM (static RAM) 的特殊存儲器芯片構成的。這種芯片比較貴,但是不需要為了保持其內容進行不斷地刷新。另一方面,傳統存儲器,即動態 RAM (dynamic RAM),就需要持續刷新。它速度慢一些,但是價格更便宜。
加載並執行程序
在程序執行之前,需要用一種工具程序將其加載到內存,這種工具程序稱為程序加載器 (program loader)。加載后,操作系統必須將 CPU 向程序的入口,即程序開始執行的地址。以下步驟是對這一過程的詳細分解。1) 操作系統(OS)在當前磁盤目錄下搜索程序的文件名。如果找不到,則在預定目錄列表(稱為路徑(path))下搜索文件名。當 OS 無法檢索到文件名時,它會發出一個出錯信息。
2) 如果程序文件被找到,OS 就訪問磁盤目錄中的程序文件基本信息,包括文件大小,及其在磁盤驅動器上的物理位置。
3) OS 確定內存中下一個可使用的位置,將程序文件加載到內存。為該程序分配內存塊,並將程序大小和位置信息加入表中(有時稱為描述符表(descriptor table))。另外,OS 可能調整程序內指針的值,使得它們包括程序數據地址。
4) OS 開始執行程序的第一條機器指令(程序入口)。當程序開始執行后,就成為一個進程(process)。OS 為這個進程分配一個標識號(進程 ID),用於在執行期間對其進行追蹤。
5) 進程自動運行。OS 的工作是追蹤進程的執行,並響應系統資源的請求。這些資源包括內存、磁盤文件和輸入輸出設備等。
6) 進程結束后,就會從內存中移除。
不論使用哪個版本的 Microsoft Windows,按下 Ctrl-Alt-Delete 組合鍵,可以選擇任務管理器(task manager)選項。在任務管理器窗口可以查看應用程序和進程列表。
應用程序列表中列出了當前正在運行的完整程序名稱,比如,Windows 瀏覽器,或者 Microsoft Visual C++。如果選擇進程列表,則會看見一長串進程名。其中的每個進程都是一個獨立於其他進程的,並處於運行中的小程序。
可以連續追蹤每個進程使用的 CPU 時間和內存容量。在某些情況下,選定一個進程名稱后,按下 Delete 鍵就可以關閉該進程。