本章重點是與 x86 匯編語言相關的底層硬件。有說法認為,匯編語言是直接與機器交流的理想軟件工具。如果是真的,那么匯編程序員就必須非常熟悉處理器的內部結構與功能。本章將討論指令執行時處理器內部發生的一些基本操作,以及操作系統如何加載和執行程序,并通過樣本主板布局來了解x86系統的硬件環境,最后還討論了在應用程序與操作系統之間,層次化輸入輸出是如何工作的。本章所有主題為開始編寫匯編語言程序提供了硬件基礎。
2.1 一般概念
本章描述了x86 處理器系列架構,以及從程序員角度看到的主機系統。其中包括了所有的Intel IA-32和Intel 64處理器,如奔騰(IntelPentium)和酷睿雙核(Core-Duo)處理器,還包括了高級微設備(AMD)處理器,如速龍(Athlon)、弈龍(Phenom)、皓龍(Opteron)和AMD64。匯編語言是學習計算機如何工作的很好的工具,它需要讀者具備計算機硬件的工作知識。為此,本章的概念和詳細信息將幫助程序員理解自己所寫的匯編代碼。
本章在所有處理器都使用的概念與 x86 處理器特點之間進行了平衡。程序員將來可能要面對各種類型的處理器,因此,本章呈現的是通用概念。同時,為了避免對機器架構形成膚淺的認知,本章也關注 x86 處理器的特性,以便具備匯編編程的堅實基礎。
若希望了解更多 IntelIA-32架構,請參閱《Intel64與IA-32 架構軟件開發手冊》的卷1:基礎架構(Intel 64 and IA-32 Architectures Software Developer'S Manual. Volume 1:BasicArchitecture)。該文檔可以從Intel網站免費下載(www,intel.com)。
2.1.1 基本微機設計
圖2-1給出了假想機的基本設計。中央處理單元(CPU)是進行算術和邏輯操作的部件,包含了有限數量的存儲位置--寄存器(register),一個高頻時鐘、一個控制單元和一個算術邏輯單元。
●時鐘(clock)對CPU內部操作與系統其他組件進行同步。
●控制單元(control unit,CU)協調參與機器指令執行的步驟序列。
●算術邏輯單元(arithmetic logic unit,ALU)執行算術運算,如加法和減法,以及邏輯運算,如 AND(與)、OR(或)和 NOT(非)。
CPU 通過主板上CPU插座的引腳與計算機其他部分相連。大部分引腳連接的是數據總線、控制總線和地址總線。內存存儲單元(memory storageunit)用于在程序運行時保存指令與數據。它接受來自 CPU 的數據請求,將數據從隨機存儲器(RAM)傳輸到 CPU,并從CPU傳輸到內存。由于所有的數據處理都在 CPU 內進行,因此保存在內存中的程序在執行前需要被復制到CPU中。程序指令在復制到CPU時,可以一次復制一條,也可以一次復制多條。
總線(bus)是一組并行線,用于將數據從計算機一個部分傳送到另一個部分。一個計算機系統通常包含四類總線:數據類、I/O 類、控制類和地址類。數據總線(data bus)在 CPU和內存之間傳輸指令和數據。I/O 總線在CPU和系統輸入/輸出設備之間傳輸數據。控制總線(control bus)用二進制信號對所有連接在系統總線上設備的行為進行同步。當前執行指令在 CPU 和內存之間傳輸數據時,地址總線(address bus)用于保持指令和數據的地址。
時鐘 CPU和系統總線相關的每一個操作都是由一個恒定速率的內部時鐘脈沖來進行同步。機器指令的基本時間單位是機器周期(machinecycle)或時鐘周期(clock cycle)一個時鐘周期的時長是一個完整時鐘脈沖所需要的時間。下圖中,一個時鐘周期被描繪為兩個相鄰下降沿之間的時間:
時鐘周期持續時間用時鐘速度的倒數來計算,而時鐘速度則用每秒振蕩數來衡量。例如,一個每秒振蕩 10 億次(1GHz)的時鐘,其時鐘周期為 10 億分之1 秒(1 納秒)。
執行一條機器指令最少需要1個時鐘周期,有幾個需要的時鐘則超過了50個(比如8088 處理器中的乘法指令)。由于在 CPU、系統總線和內存電路之間存在速度差異,因此,需要訪問內存的指令常常需要空時鐘周期,也被稱為等待狀態(wait states)。
2.1.2 指令執行周期
一條機器指令不會神奇地一下就執行完成。CPU在執行一條機器指令時,需要經過一系列預先定義好的步驟,這些步驟被稱為指令執行周期(instruction execution cycle)。假設現在指令指針寄存器中已經有了想要執行指令的地址,下面就是執行步驟:
1)CPU 從被稱為指令隊列(instructionqueue)的內存區域取得指令,之后立即增加指令指針的值。
2)CPU對指令的二進制位模式進行譯碼。這種位模式可能會表示該指令有操作數(輸入值)。
3)如果有操作數,CPU就從寄存器和內存中取得操作數。有時,這步還包括了地址計算。
4)使用步驟3得到的操作數,CPU執行該指令。同時更新部分狀態標志位,如零標志(Zero)、進位標志(Carry)和溢出標志(Overflow)。
5)如果輸出操作數也是該指令的一部分,則 CPU 還需要存放其執行結果。
通常將上述聽起來很復雜的過程簡化為三個步驟:取指(Fetch)、譯碼(Decode)和執行(Execute)。操作數(operand)是指操作過程中輸入或輸出的值。例如,表達式Z=X+Y有兩個輸入操作數(X 和Y),一個輸出操作數(Z)。
圖2-2是一個典型CPU中的數據流框架圖。該圖表現了在指令執行周期中相互交互部件之產是的關系。在從內存讀取程序指令之前,將其地址放到地址總線上。然后,內存控制器將所需代碼送到數據總線上,存入代碼高速緩存(code cache)。指令指針的值決定下一條將要執行的指令。指令由指令譯碼器分析,并產生相應的數值信號送往控制單元,其協調ALU和浮點單元。雖然 圖中沒有畫出控制總線,但是其上傳輸的信號用系統時鐘協調不同CPU部件之間的數據傳輸。
2.1.3 讀取內存
作為一個常見現象,計算機從內存讀取數據比從內部寄存器讀取速度要慢很多。這是因為從內存讀取一個值,需要經過下述步驟:
1)將想要讀取的值的地址放到地址總線上。
2)設置處理器RD(讀取)引腳(改變RD的值)。
3)等待一個時鐘周期給存儲器芯片進行響應。
4)將數據從數據總線復制到目標操作數。
上述每一步常常只需要一個時鐘周期,時鐘周期是基于處理器內固定速率時鐘節拍的一種時間測量方法。計算機的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(staticRAM)的特殊存儲器芯片構成的。這種芯片比較貴,但是不需要為了保持其內容進行不斷地刷新。另一方面,傳統存儲器,即動態RAM(dynamic RAM),就需要持續刷新。它速度慢一些,但是價格更便宜。
2.1.4 加載并執行程序
在程序執行之前,需要用一種工具程序將其加載到內存,這種工具程序稱為程序加載器(program loader)。加載后,操作系統必須將CPU 指向程序的入口,即程序開始執行的地址。以下步驟是對這一過程的詳細分解。
●操作系統(OS)在當前磁盤目錄下搜索程序的文件名。如果找不到,則在預定目錄列表(稱為路徑(path))下搜索文件名。當OS 無法檢索到文件名時,它會發出一個出錯信息。
●如果程序文件被找到,OS 就訪問磁盤目錄中的程序文件基本信息,包括文件大小,及其在磁盤驅動器上的物理位置。
●OS確定內存中下一個可使用的位置,將程序文件加載到內存。為該程序分配內存塊,并將程序大小和位置信息加入表中(有時稱為描述符表(descriptor table))。另外,OS 可能調整程序內指針的值,使得它們包括程序數據地址。
●OS 開始執行程序的第一條機器指令(程序入口)。當程序開始執行后,就成為一個進程(process)。OS 為這個進程分配一個標識號(進程ID),用于在執行期間對其進行追蹤。
●進程自動運行。OS 的工作是追蹤進程的執行,并響應系統資源的請求。這些資源包括內存、磁盤文件和輸入輸出設備等。
●進程結束后,就會從內存中移除。
提示? 不論使用哪個版本的Microsoft Windows,按下Ctrl-Alt-Delete組合鍵,可以選擇任務管理器(task manager)選項。在任務管理器窗口可以查看應用程序和進程列表。應用程序列表中列出了當前正在運行的完整程序名稱,比如,Windows 瀏覽器,或者Microsoft Visual C++。如果選擇進程列表,則會看見一長串進程名。其中的每個進程都是一個獨立于其他進程的,并處于運行中的小程序。可以連續追蹤每個進程使用的CPU 時間和內存容量。在某些情況下,選定一個進程名稱后,按下 Delete 鍵就可以關閉該進程。
2.1.5 本節回顧
1.中央處理單元(CPU)包含寄存器和哪些其他基本部件?
答:控制單元、算術邏輯單元和時鐘
2.中央處理單元通過哪三種總線與計算機系統的其他部分相連?
答:數據、地址和控制總線
3.為什么訪問存儲器比訪問寄存器要花費更多的機器周期?
答:通常內存位于CPU之外,對訪問請求的響應要更慢一些。寄存器則是硬連接在CPU內。
4.指令執行周期包含哪三個基本步驟?
答:取指、譯碼、執行。
5.指令執行周期中,如果用到存儲器操作數,則還需要哪兩個步驟?
答:取內存操作數,存內存操作數。
2.2 32位X86處理器
本節重點在于所有x86處理器的基本架構特點。這些處理器包括了Intel IA-32 系列中的成員和所有32位AMD處理器。
2.2.1操作模式
x86處理器有三個主要的操作模式:保護模式、實地址模式和系統管理模式;以及一個子模式:虛擬8086(virtual-8086)模式,這是保護模式的特殊情況。以下是對這些模式的簡介:
保護模式(Protected Mode) 保護模式是處理器的原生狀態,在這種模式下,所有的指令和特性都是可用的。分配給程序的獨立內存區域被稱為段,而處理器會阻止程序使用自身段范圍之外的內存。
虛擬8086模式(Virtual-8086Mode) 保護模式下,處理器可以在一個安全環境中,直接執行實地址模式軟件,如 MS-DOS 程序。換句話說,如果一個程序崩潰了或是試圖向系統內存區域寫數據,都不會影響到同一時間內執行的其他程序。現代操作系統可以同時執行多個獨立的虛擬8086 會話。
實地址模式(Real-AddressMode) 實地址模式實現的是早期Intel處理器的編程環境,但是增加了一些其他的特性,如切換到其他模式的功能。當程序需要直接訪問系統內存和硬件設備時,這種模式就很有用。
系統管理模式(System Management Mode) 系統管理模式(SMM)向操作系統提供了實現諸如電源管理和系統安全等功能的機制。這些功能通常是由計算機制造商實現的,他們為了一個特定的系統設置而定制處理器。
2.2.2 基本執行環境
1.地址空間
在32 位保護模式下,一個任務或程序最大可以尋址 4GB 的線性地址空間。從 P6 處理器開始,一種被稱為擴展物理尋址(extended physicaladdressing)的技術使得可以被尋址的物理內存空間增加到64GB。與之相反,實地址模式程序只能尋址1MB空間。如果處理器在保護模式下運行多個虛擬 8086 程序,則每個程序只能擁有自己的 1MB 內存空間。
2.基本程序執行寄存器
寄存器是直接位于CPU內的高速存儲位置,其設計訪問速度遠高于傳統存儲器。例如,當一個循環處理為了速度進行優化時,其循環計數會保留在寄存器中而不是變量中。圖2-3展示的是基本程序執行寄存器(basic program execution registers)。8個通用寄存器,6個段寄存器,一個處理狀態標志害存器(EFLAGS),和一個指令指針寄存器(EIP)。
通用寄存器 通用寄存器主要用于算術運算和數據傳輸。如圖2-4所示,EAX寄存器的低16位在使用時可以用AX表示。
一些寄存器的組成部分可以處理8位的值。例如,AX寄存器的高8位被稱為AH,而低8位被稱為AL。同樣的重疊關系也存在于EAX、EBX、ECX和EDX寄存器中;
32位 | 16位 | 8位(高) | 8位(低) |
EAX | AX | AH | AL |
EBX | BX | BH | BL |
ECX | CX | CH | CL |
EDX | DX | DH | DL |
其他通用寄存器只能用32位或16位名稱來訪問,如下表所示:
32位 | 16位 | 32位 | 16位 |
ESI | SI | EBP | BP |
EDI | DI | ESP | SP |
特殊用法 某些通用寄存器有特殊用法:
●乘除指令默認使用EAX。它常常被稱為擴展累加器(extended accumulator)寄存器。
●CPU默認使用ECX 為循環計數器。
●ESP 用于尋址堆棧(一種系統內存結構)數據。它極少用于一般算術運算和數據傳輸,通常被稱為擴展堆棧指針(extended stack pointer)寄存器。
●ESI 和 EDI 用于高速存儲器傳輸指令,有時也被稱為擴展源變址(extended sourceindex)寄存器和擴展目的變址(extended destination index)寄存器。
●高級語言通過 EBP 來引用堆棧中的函數參數和局部變量。除了高級編程,它不用于一般算術運算和數據傳輸。它常常被稱為擴展幀指針(extended frame pointer)寄存器。
段寄存器 實地址模式中,16位段寄存器表示的是預先分配的內存區域的基址,這個內存區域稱為段。保護模式中,段寄存器中存放的是段描述符表指針。一些段中存放程序指令(代碼),其他段存放變量(數據),還有一個堆棧段存放的是局部函數變量和函數參數。
指令指針 指令指針(EIP)寄存器中包含下一條將要執行指令的地址。某些機器指令能控制EIP,使得程序分支轉向到一個新位置。
EFLAGS寄存器 EFLAGS(或Flags)寄存器包含了獨立的二進制位,用于控制CPU的操作,或是反映一些CPU操作的結果。有些指令可以測試和控制這些單獨的處理器標志位。
設置標志位時,該標識位=1;清除(或重置)標識位時,該標志位=0.
控制標志位 控制標志位控制 CPU 的操作。例如,它們能使得 CPU 每執行一條指令后進入中斷;在偵測到算術運算溢出時中斷執行;進入虛擬 8086模式,以及進入保護模式。
程序能夠通過設置EFLAGS寄存器中的單獨位來控制CPU的操作,比如,方向標志位和中斷標志位。
狀態標志位 狀態標志位反映了CPU執行的算術和邏輯操作的結果。其中包括:溢出位、符號位、零標志位、輔助進位標志位、奇偶校驗位和進位標志位。下述說明中,標志位的縮寫緊跟在標志位名稱之后:
●進位標志位(CF),與目標位置相比,無符號算術運算結果太大時,設置該標志位。
●溢出標志位(OF),與目標位置相比,有符號算術運算結果太大或太小時,設置該標志位。
●符號標志位(SF),算術或邏輯操作產生負結果時,設置該標志位。
●零標志位(ZF),算術或邏輯操作產生的結果為零時,設置該標志位。
●輔助進位標志位(AC),算術操作在8位操作數中產生了位3向位 4的進位時,設置該標志位。
●奇偶校驗標志位(PF),結果的最低有效字節包含偶數個1時,設置該標志位,否則,清除該標志位。一般情況下,如果數據有可能被修改或損壞時,該標志位用于進行錯誤檢測。
3.MMX 寄存器
在實現高級多媒體和通信應用時,MMX技術提高了Intel 處理器的性能。8 個 64 位MMX 寄存器支持稱為SIMD(單指令,多數據,Single-Instruction,Multiple-Data)的特殊指令。顧名思義,MMX 指令對 MMX 寄存器中的數據值進行并行操作。雖然,它們看上去是獨立的寄存器,但是MMX寄存器名實際上是浮點單元中使用的同樣寄存器的別名。
4.XMM 寄存器
x86 結構還包括了 8 個 128 位 XMM 寄存器,它們被用于 SIMD 流擴展指令集。
浮點單元 浮點單元(FPU,floating-point unit)執行高速浮點算術運算。之前為了這個目的,需要一個獨立的協處理器芯片。從Intel486 處理器開始,FPU 已經集成到主處理器芯片上。FPU中有8個浮點數據寄存器,分別命名為ST(0)ST(1)ST(2)ST(3),ST(4),ST(5),ST(6)和ST(7)。其他控制寄存器和指針寄存器如圖 2-5 所示。
2.2.3 x86 內存管理
x86 處理器按照 2.2.1 節中討論的基本操作模式來管理內存。保護模式是最可靠、最強大的,但是它對應用程序直接訪問系統硬件有著嚴格的限制。
在實地址模式中,只能尋址1MB 內存,地址從00000H到FFFFFH。處理器一次只能運行一個程序,但是可以暫時中斷程序來處理來自外圍設備的請求(稱為中斷(interrupt))。應用程序被允許訪問內存的任何位置,包括那些直接與系統硬件相關的地址。MS-DOS 操作系統在實地址模式下運行,Windows95和98能夠引導進人這種模式。
在保護模式中,處理器可以同時運行多個程序,它為每個進程(運行中的程序)分配總共 4GB 的內存。每個程序都分配有自己的保留內存區域,程序之間禁止意外訪問其他程序的代碼和數據。MS-Windows 和Linux運行在保護模式下。
在虛擬 8086 模式中,計算機運行在保護模式下,通過創建一個帶有1MB地址空間的虛擬8086 機器來模擬運行于實地址模式的 80x86計算機。例如,在Windows NT和2000下.當打開一個命令窗口時,就創建了一個虛擬 8086 機器。同一時間可以運行多個這樣的窗口,并且窗口之間都是受到保護的。在 Windows NT,2000和XP 系統中,某些需要直接使用計算機硬件的MS-DOS程序不能運行在虛擬8086模式下。
實地址模式和保護模式的更多細節將在第11章中進行詳述。
2.2.4 本節回顧
1.x86處理器的3個基本操作模式是什么?
答:實地址模式、保護模式和系統管理模式
2.給出8個32 位通用寄存器的名稱。
答:EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP
3.給出6個段寄存器的名稱。
答:CS、DS、SS、ES、FS、GS
4.ECX 寄存器的特殊用途是什么?
答:循環計數器
2.3 64位x86-64處理器
本節重點關注所有使用x86-64指令集的64位處理器的基本架構細節。這些處理器包括Intel 64 和 AMD64 處理器系列。指令集是已討論的 x86 指令集的 64 位擴展。以下為一些基本特征:
1)向后兼容 x86 指令集。
2)地址長度為 64 位,虛擬地址空間為264字節。按照當前芯片的實現情況,只能使用地址的低 48 位。
3)可以使用 64 位通用寄存器,允許指令具有 64 位整數操作數。
4)比x86多了8個通用寄存器。
5)物理地址為48 位,支持高達 256TB的RAM。
另一方面,當處理器運行于本機64位模式時,是不支持16位實模式或虛擬8086 模式的。(在傳統模式(legacy mode)下,還是支持16位編程,但是在Microsoft Windows 64位版本中不可用。)
注意 盡管x86-64指的是指令集,但是也可以將其看作是處理器類型。學習匯編語言時,沒有必要考慮支持x86-64的處理器之間的硬件實現差異。
第一個使用x86-64的Intel處理器是Xeom,之后還有許多其他的處理器,包括Core i5和Core i7。AMD處理器中使用x86-64的例子有Opteron和Athlon 64。
另一個為人所知的64位Intel架構是IA-64,后來被稱為Itanium。IA-64指令集與x86和 x86-64 完全不同,Itanium 處理器通常用于高性能數據庫和網絡服務器。
2.3.1 64位操作模式
Intel 64架構引入了一個新模式,稱為IA-32e。從技術上看,這個模式包含兩個子模式:兼容模式(compatibilitymode)和64位模式(64-bitmode)。不過它們常常被看做是模式面不是子模式,因此,先來了解這兩個模式。
1. 兼容模式
在兼容模式下,現有的16 位與32 位應用程序通常不用進行重新編譯就可以運行。但是,16位Windows(Win16)和DOS應用程序不能運行在64位Microsoft Windows下。與早期 Windows 版本不同,64位Windows沒有虛擬DOS機器子系統來利用處理器的功能切換到虛擬8086 模式。
2. 64位模式
在64位模式下,處理器執行的是使用64位線性地址空間的應用程序。這是 64位Microsoft Windows 的原生模式,該模式能使用64 位指令操作數。
2.3.2 基本64位執行環境
64 位模式下,雖然處理器現在只能支持 48 位的地址,但是理論上,地址最大為 64 位。從寄存器來看,64 位模式與 32 位最主要的區別如下所示:
●16個64位通用寄存器(32位模式只有8個通用寄存器)
●8個80位浮點寄存器
●1個64位狀態標志寄存器RFLAGS(只使用低32位)
●1 個 64 位指令指針寄存器
RIP回顧前文,32 位標志寄存器和指令指針寄存器分別稱為 EFLAGS 和 EIP。此外,還有一些在討論x86 處理器時提過的,用于多媒體處理的特殊寄存器:
●8 個64 位 MMX 寄存器
●16個128位XMM寄存器(32位模式只有8個XMM寄存器)
通用寄存器
在描述 32 位處理器時介紹過通用寄存器,它們是算術運算、數據傳輸和循環遍歷數據指令的基本操作數。通用寄存器可以訪問8位、16 位、32 位或 64 位操作數(需使用特殊前綴)。
64 位模式下,操作數的默認大小是32 位,并且有8個通用寄存器。但是,給每條指令加上REX(寄存器擴展)前綴后,操作數可以達到 64 位,可用通用寄存器的數量也增加到16 個:32 位模式下的寄存器,再加上8個有標號的寄存器,R8 到 R15。表 2-1 給出了REX前綴下可用的寄存器。
表2-1 使用REX前綴后,64位模式的操作數據大小 | |
操作數大小 | 可用寄存大 |
8位 | AL、BL、CL、DL、DIL、SIL、BPL、SPL、R8L、R9L、R10L、R11L、R12L、R13L、R14L、R15L |
16位 | AX、BX、CX、DX、DI、SI、BP、SP、R8W、R9W、R10W、R11W、R12W、R13W、R14W、R15W |
32位 | EAX、EBX、ECX、EDX、EDI、ESI、EBP、ESP、R8D、R9D、R10D、R11D、R12D、R13D、R14D、R15D |
64位 | RAX、RBX、RCX、RDX、RDI、RSI、RBP、RSP、R8、R9、R10、R11、R12、R13、R14、R15 |
還有一些需要記住的細節:
●64 位模式下,單條指令不能同時訪問寄存器高字節,如 AH、BH、CH 和DH,及新字節寄存器的低字節(如 DIL)。
●64 位模式下,32 位 EFLAGS 寄存器由 64 位 RFLAGS 寄存器取代。這兩個寄存器共享低 32 位,而 RFLAGS 的高 32 位是不使用的。
●32 位模式和 64 位模式具有相同的狀態標志。
2.4 典型x86計算機組件
本節首先通過檢查典型主板配置以及圍繞CPU的芯片組來了解x86如何與其他組件的集成。然后討論內存、I/O端口和通用設備接口。最后說明匯編語言程序怎樣利用系統硬件、固件,并調用操作系統函數來實現不同訪問層次的 I/O 操作。
2.4.1 主板
主板是微型計算機的心臟,它是一個平面電路板,其上集成了CPU、支持處理器(芯片組(chipset))、主存、輸入輸出接口、電源接口和擴展插槽。各種組件通過總線即一組直接蝕刻在主板上的導線,進行互連。目前 PC 市場上有幾十種主板,它們在擴展功能、集成部件和速度方面存在著差異。但是,下述組件一般都會出現在主板上:
●CPU插座。根據其支持的處理器類型,插座具有不同的形狀和尺寸。
●存儲器插槽(SIMM 或DIMM),用于直接插人小型內存條。
●BIOS(基本輸入輸出系統,basic input-output system)計算機芯片,保存系統軟件。
●CMOS RAM,用一個小型紐扣電池為其持續供電。
●大容量插槽設備接口,如硬盤和 CD-ROMS。
● 外部設備的 USB 接口。
●鍵盤和鼠標接口。
●PCI 總線接口,用于聲卡、顯卡、數據采集卡和其他輸入輸出設備。
以下是可選組件:
●集成聲音處理器。
●并行和串行設備接口。
●集成網卡。
●用于高速顯卡的AGP 總線接口。
典型系統中還有一些重要的支持處理器:
●浮點單元(FPU),處理浮點數和擴展整數運算。
●8284/82C84 時鐘發生器,簡稱時鐘,按照恒定速率振蕩。時鐘發生器同步 CPU 和計算機的其他部分。
●8259A可編程中斷控制器(PIC,Programmable InterruptController),處理來自硬件設備的外部中斷請求,包括鍵盤、系統時鐘和磁盤驅動器。這些設備能中斷 CPU,并使其立即響應它們的請求。
●8253可編程間隔定時器/計數器(Programmable Interval Timer/Counter),每秒中斷系統18.2次,更新系統日期和時鐘,并控制揚聲器。它還負責不斷刷新內存,因為RAM存儲器芯片保持其內容的時間只有幾毫秒。
●8255可編程并行端口(Programmable Parallel Port),使用IEEE并行端口將數據輸入和輸出計算機。該端口通常用于打印機,但是也可以用于其他輸出設備。
1. PCI和PCI Express總線架構
PCI(外部設備互聯,Peripheral Component Interconnect)總線為CPU和其他系統設備提供了連接橋,這些設備包括硬盤驅動器、內存、顯卡、聲卡和網卡。最近,PCI Express總線在設備、內存和處理器之間提供了雙向串行連接。如同網絡一樣,它用獨立的“通道”傳送數據包。該總線得到顯卡的廣泛支持,能以較高速度傳輸數據。
2.主板芯片組
主板芯片組(motherboard chipset)是一組處理器芯片的集合,這些芯片被設計為在特定類型主板上一起工作。各種芯片組具有增強處理能力、多媒體功能或減少功耗等特性。以Intel P965 Express 芯片組為例,該芯片組與Intel Core2 Duo 或 Pentium D 處理器一起,用于桌面系統。Intel P965 具有下述特性:
●Intel 高速內存訪問(Fast Memory Access)使用了最新內存控制中心(MCH)。它可以800MHz時鐘速度來訪問雙通道DDR2存儲器。
●I/O 控制中心(Intel ICH8/R/DH)使用Intel矩陣存儲技術(MST)來支持多個串行ATA 設備(磁盤驅動器)。支持多個 ●USB 端口,多個 PCI Express 插槽,聯網和 Intel 靜音系統技術。
●高清晰音頻芯片提供了數字聲音功能。
如圖 2-6 所示,主板廠商以特定芯片為中心來制造產品。例如,Asus 公司使用 P965 芯片組的 P5B-E P965 主板。
來源:Intel P965 Express芯片組(產品簡介),Intel公司版權所有,已獲使用權。
2.4.2 內存
基于 Intel 的系統使用的是幾種基礎類型內存:只讀存儲器(ROM)、可擦除可編程只讀存儲器(EPROM)、動態隨機訪問存儲器(DRAM)、靜態 RAM(SRAM)、圖像隨機存儲器(VRAM),和互補金屬氧化物半導體(CMOS)RAM:
●ROM 永久燒錄在芯片上,并且不能擦除。
●EPROM 能用紫外線緩慢擦除,并且重新編程。·
●DRAM,即通常的內存,在程序運行時保存程序和數據的部件。該部件價格便宜,但是每毫秒需要進行刷新,以避免丟失其內容。有些系統使用的是ECC(錯誤檢查和糾正)存儲器。
●SRAM 主要用于價格高、速度快的 cache 存儲器。它不需要刷新,CPU 的 cache 存儲器就是由 SRAM 構成的。
●VRAM 保存視頻數據。VRAM 是雙端口的,它允許一個端口持續刷新顯示器,同時另一個端口將數據寫到顯示器。
●CMOS RAM 在系統主板上,保存系統設置信息。它由電池供電,因此當計算機電源關閉后,CMOS RAM 中的內容仍能保留。
2.4.3 本節回顧
1.描述 SRAM 及其最常見的用途。
答:SRAM是靜態RAM的縮寫,用于CPU高速緩存。
2.描述VRAM。
答:VRAM(顯存)保存可顯示的圖像數據。當使用CRT監視器時,VRAM是雙端口的,其中一個端口持續刷新顯示器,另一個端口向顯示器寫入數據。
3.列出Intel P965 Express 芯片組至少兩個特性。
答:可從下面敘述中任選兩個特性:(1)Intel快速內存訪問使用了最新內存控制單元(MCH)。(2)I/O控制中心(Intel ICH8/R/DH)支持串行ATA設備(磁盤驅動器)。(3)支持10個USB端口、6個PCI Express插槽、聯網和Intel靜音系統技術。(4)高清晰音頻芯片。
4.寫出本章描述的4類RAM。
答:動態RAM,靜態RAM,視頻RAM和CMOS RAM。
5.8259A PIC控制器的用途是什么?
答:8259A PIC控制器處理來自鍵盤、系統時鐘和磁盤驅動器等硬件設備的外部中斷。
2.5 輸入輸出系統
提示 由于計算機游戲與內存和I/O有著非常密切的關系,因此,它們推動計算機達到其最大性能。善于游戲編程的程序員通常很了解視頻和音頻硬件,并會優化代碼的硬件特性。
2.5.1 I/O訪問層次
應用程序通常從鍵盤和磁盤文件讀取輸人,而將輸出寫到顯示器和文件中。完成 I/0 不需要直接訪問硬件--相反,可以調用操作系統的函數。與第1章中描述的虛擬機相似,I/O也有不同的訪問層次,主要有以下三個:
●高級語言函數:高級編程語言,如 C++或Java,包含了執行輸入輸出的函數。由于這些函數要在各種不同的計算機系統中工作,并不依賴于任何一個操作系統,因此,這些函數具有可移植性。
●操作系統:程序員能夠從被稱為API(應用程序編程接口,Application ProgrammingInterface)的庫中調用操作系統函數。操作系統提供高級操作,比如,向文件寫人字符串,從鍵盤讀取字符串,和分配內存塊。
●BIOS:基本輸入輸出系統是一組能夠直接與硬件設備通信的低級子程序集合。BIOS由計算機制造商安裝并定制,以適應機器硬件。操作系統通常與BIOS 通信。
設備驅動程序 設備驅動程序允許操作系統與硬件設備和系統 BIOS 直接通信。例如,設備驅動程序可能接收來自 OS 的請求來讀取一些數據,而滿足該請求的方法是,通過執行設備固件中的代碼,用設備特有的方式來讀取數據。設備驅動程序有兩種安裝方法:(1)在特定硬件設備連接到系統之前,或者(2)設備已連接并且識別之后。對于后一種方法,OS識別設備名稱和簽名,然后在計算機上定位并安裝設備驅動軟件。
現在,通過展示應用程序在屏幕上顯示字符串的過程,來了解I/O層次結構(圖2-7)
該過程包含以下步驟:
1)應用程序調用HLL庫函數,將字符串寫入標準輸出。
2)庫函數(第3層)調用操作系統函數,傳遞一個字符串指針。
3)操作系統函數(第2層)用循環的方法調用BIOS子程序,向其傳遞每個字符的ASCII碼和顏色。操作系統調用另一個BIOS子程序,將光標移動到屏幕的下一個位置上。
4)BIOS子程序(第2層)接收一個字符,將其映射到一個特定的系統字體,并把該字符發送與視頻控制卡相連的硬件端口。
5)視頻控制卡(第0層)為視頻顯示產生定時硬件信號,來控制光柵掃描并顯示像素。
多層次編程 匯編語言程序在輸入輸出編程領域有著強大的能力和靈活性。它們可以從以下訪問層次進行選擇(圖2-8):
●第 3 層:調用庫函數來執行通用文本 I/O 和基于文件的 I/O。例如,本書也提供了一個這樣的庫。
●第2層:調用操作系統函數來執行通用文本I/O和基于文件的I/O。如果OS使用了圖形用戶界面,它就能用與設備無關的方式來顯示圖形。
●第 1 層:調用BIOS 函數來控制設備具體特性,如顏色、圖形、聲音、鍵盤輸入和底層磁盤I/O。
●第0層:從硬件端口發送和接收數據,對特定設備擁有絕對控制權。這個方式沒有廣泛用于各種硬件設備,因此不具可移植性。不同設備通常使用不同硬件端口,因此,程序代碼必須根據每個設備的特定類型來進行定制。
如何進行權衡?控制與可移植性是最重要的。第2層(OS)工作在任何一個運行同樣操作系統的計算機上。如果I/O 設備缺少某些功能,那么OS 將盡可能接近預期結果。第2層速度并不特別快,因為每個1/O 調用在執行前,都必須經過好幾個層次。
第1層(BIOS)在具有標準BIOS的所有系統上工作,但是在這些系統上不會產生同樣的結果。例如,兩臺計算機可能會有不同分辨率的視頻顯示功能。在第 1層上的程序員需要編寫代碼來檢測用戶的硬件設置,并調整輸出格式來與之匹配。第1層的速度比第 2層快,因為它與硬件之間只隔了一個層次。
第0層(硬件)與通用設備一起工作,如串行端口;或是與由知名廠商生產的特殊I/O設備一起工作。這個層次上的程序必須擴展它們的編碼邏輯來處理I/O 設備的變化。實模式的游戲程序就是最好的例子,因為它們常常需要取得計算機的控制權。第 0 層的程序執行速度與硬件一樣快。
舉個例子,假設要用音頻控制設備來播放一個WAV文件。在OS層上,不需要了解已安裝設備的類型,也不用關心設備卡的非標準特性。在 BIOS 層上,要查詢聲卡(通過其已安裝的設備驅動軟件),找出它是否屬于某一類具有已知功能的聲卡。在硬件層上,需要對特定模式聲卡的程序進行微調,以利用每個聲卡的特性。
通用操作系統極少允許應用程序直接訪問系統硬件,因為這樣做會使得它幾乎無法同時運行多個程序。相反,硬件只能由設備驅動程序按照嚴格控制的方式進行訪問。另一方面,專業設備的小型操作系統則常常直接與硬件相連。這樣做是為了減少操作系統代碼占用的內存空間,并且這些操作系統幾乎總是一次只運行單個程序。Microsoft 最后一個允許程序直接訪問硬件的操作系統是MS-DOS,它一次只能運行一個程序。
2.5.2 本節回顧
1.計算機系統中有4個輸入輸出層次,哪一個最具有通用性和可移植性?
答:應用程序層
2.區分BIOS 層輸入輸出的特征是什么?
答:BIOS函數直接與系統硬件通信。它們獨立于操作系統。
3.考慮到BIOS中已經有了與計算機硬件通信的代碼,為什么設備驅動程序是必需的?
答:編寫BIOS的時候通常不可能預見到新發明設備的功能。
4.在顯示字符串的例子中,操作系統與視頻控制卡之間存在的是哪個I/O 層次?
答:BIOS層
5.運行MS-Windows 和運行Linux的計算機的BIOS可能存在不同嗎?
答:不可能,相同的BIOS適用于這兩種操作系統。很多計算機用戶會在同一臺機器上安裝兩個或三個操作系統。他們肯定不想在每次重啟計算時切換系統BIOS。
2.6 本章小結
中央處理單元(CPU)處理算術和邏輯運算。它包含了有限數量的存儲位置,即寄存器,一個高頻時鐘用于同步其操作,一個控制單元和一個算術邏輯單元。內存存儲單元在計算機程序運行時,保存指令和數據。總線是一組并行線路,在計算機不同部件之間傳輸數據。
一條機器指令的執行可以分為一系列獨立的操作,稱為指令執行周期。3個主要操作分別為取值、譯碼和執行。指令周期中的每一步都至少要花費一個系統時鐘單位,即時鐘周期。加載和執行過程描述了程序如何被操作系統定位,加載入內存,再由操作系統執行。
x86處理器系列有三種基本操作模式:保護模式、實地址模式和系統管理模式。此外,還有一個虛擬8086模式是保護模式的一個特例。Intel 64處理器系列有兩種操作模式:兼容模式和64位模式。在兼容模式下處理器可以運行16位和32位應用程序。
寄存器為 CPU 內的存儲位置進行命名,其訪問速度比常規內存要快很多。以下是對寄存器的簡要說明:
●通用寄存器主要用于算術運算、數據傳輸和邏輯操作。
●段寄存器存放預先分配的內存區域的基址,這些內存區域就是段。
●指令指針寄存器存放的是下一條要執行指令的地址。
●標志寄存器包含的獨立二進制位用于控制CPU的操作,并反映ALU操作的結果。
x86有一個浮點單元(FPU)專門用于高速浮點指令的執行。微型計算機的心臟是它的主板,主板上有CPU、支持處理器、主存、輸入輸出接口、電源接口和擴展插槽。PCI(外部設備互聯)總線為Pentium處理器提供了方便的升級途徑。大多數主板集成了若干微處理器和控制器,稱為芯片組。芯片組在很大程度上決定了計算機的性能。
PC 中使用的幾種基本存儲器為:ROM、EPROM、動態RAM(DRAM)、靜態RAM(SRAM)、視頻RAM(VRAM)和CMOSRAM。
與虛擬機概念相似,輸入輸出是通過不同層次的訪問來實現的。庫函數在最高層,操作系統是次高層。BIOS(基本輸入輸出系統)是一組函數,能直接與硬件設備通信。程序也可以直接訪問輸入輸出設備。
2.7 關鍵術語
32-bit mode(32 位模式) | flags register(標志寄存器) |
64-bit mode(64 位模式) | floating-poing unit(浮點單元) |
address bus(地址總線) | general-purposeregisters(通用寄存器) |
application programming interface(API)(應用程序接口) | basic program execution registers(基本程序執行寄存器) |
arithmetic logic unit(ALU)(算術邏輯單元) | instruction decoder(指令譯碼器) |
auxiliary carry flag(輔助進位標志位) | BIOS(basic input-out put system)(基本輸入輸出系統) |
bus(總線) | cache(高速緩存) |
instruction excution cycle(指令執行周期) | instruction queue(指令隊列) |
instruction pointer(指令指針) | interrupt flag(中斷標志位) |
Level-1cache(1級cache) | Level-2 cache(2 級cache) |
machine cycle(機器周期) | memorystorage unit(內存存儲單元) |
MMX registers(MMX 寄存器) | carryflag(進位標志位) |
motherboard(主板) | central processor unit(CPU)(中央處理單元) |
clock(時鐘) | data bus(數據總線) |
clock cycle(時鐘周期) | data cache(數據cache ) |
clock generator(時鐘發生器) | device drivers(設備驅動程序) |
code cache(代碼cache) | direction flag(方向標志位) |
controlflags(控制標志位) | bynamic RAM(動態RAM) |
controlunit(控制單元) | EFLAGS register(EFLAGS 寄存器) |
extended destination index(擴展目的變址) | extended physical addressing(擴展物理尋址) |
extended sourceindex(擴展源變址) | extended stack pointer(擴展堆棧指針) |
fetch-decode-execute(取值-譯碼-執行) | motherboard chipset(主板芯片組) |
operating system(OS)(操作系統) | overflowflag(溢出標志位) |
parity flag(奇偶標志位) | PCI (peripheral component interconnect)(外部設備互聯) |
PCI expressprocess(過程) | process ID(過程 ID) |
programmable interrupt controller(PIC)(可編程中斷控制器) | programmable interval interval timer/counter( 編程間隔定時器/計數器) |
programmable parallelport(可編程并行端口) | protected mode(保護模式) |
randomaccess memory(RAM)(隨機訪問存儲器 | read-only memory(ROM)(只讀存儲器) |
real-address mode(實地址模式) | registers(寄存器) |
segment registers(段寄存器 | signfag(符號標志位) |
single-instruction,multiple-data(SIMD)(單指令多數據) | system management mode(SMM)(系統管理模式) |
static RSM(靜態RAM) | status flags(狀態標志位) |
Task Manager(任務管理器) | virtual-8086 mode(虎擬8086 模式) |
wait states(等待狀態) | XMM registers(XMM寄存器) |
zero flag(零標志位) |