計算機組成原理 — 指令系統
目錄
文章目錄
目錄
前文列表
指令系統
計算機指令集與程序指令
指令格式
指令類型
指令尋址
通過 MIPS 感受指令字的設計
前文列表
《計算機組成的基本硬件設備》
《計算機組成原理 — 馮諾依曼體系結構》
《計算機組成原理 — 中央處理器》
指令系統
指令系統決定了計算機的基本功能。計算機的性能與它所設置的指令系統有很大的關系,而指令系統的設置又與機器的硬件結構密切相關。指令系統的改進主要圍繞縮小指令與高級語言的語義差異以及有利于操作系統的優化而進行的,例如:高級語言中經常用到的 if 語句、do 語句,所以設置了功能較強的條件跳轉指令;為了操作系統的實現和優化,設置了有控制系統狀態的特權指令、管理多道程序和多處理機系統的專用指令。
然后指令系統太過于復雜并不完全是好事,在大多數場景中實際上只有算術邏輯運算、數據傳輸、跳轉和程序調用等幾十條指令會被頻繁的使用到,而需要大量硬件支持的大多數復雜的指令卻并不常用,由此會造成硬件資源的浪費。為了解決這個問題,指令系統被分為 精簡指令系統計算機(RISC) 和 復雜指令系統計算機(CISC)。
計算機指令集與程序指令
計算機指令集是 CPU 提供的可執行指令的集合;而程序所描述的指令是程序員希望在 CPU 上執行的指令,這些指令的范圍不會超出計算機指令集的范圍。不同類型的 CPU 能夠理解不同的 “語言”,即具有不同的計算機指令集(Instruction Set)。同一個程序可以在相同型號的 CPU 中運行,反之則無法運行。
CPU 運行一個計算機程序的本質就是運行這個程序所描述的指令,有如我們在 Linux 操作系統上執行指令一般,只是前者由 CPU 硬件支持。一個計算機程序通常由成千上萬條指令組成,CPU 顯然不能存放所有的指令,而是將這些指令存放在存儲器中,只有在運行時才會被 CPU 讀取。又因為現代計算機被設計為可以運行多種程序,存儲器被各種各樣的程序共享著,所以存儲器也不會持久化的保存它們。而是當我們要運行(啟動)某個程序時,才會將其加載到存儲器中,最終再由 CPU 從存儲器中逐一讀取其指令。我們常見的內部存儲器多為 RAM(隨機存儲器),這是一種被設計成掉電就會自動重置的存儲設備。
以上就是馮·諾依曼機的典型特性,所以又稱之為 “存儲程序計算機”。馮·諾依曼體系結構解決了計算機實現領域的一個重要難題:如何能夠動態加載程序指令。解決了這個問題,“計算器” 才得以成為 “計算機”,我們今天才得以在計算機上運行各種各樣的應用程序。
注:計算器的 “程序” 是焊死在主板上的。
指令格式
計算機是通過執行指令來處理各種數據的,為了了解數據的來源、操作結果的去向及所執行的操作類型,一條計算機指令一般包含以下信息。
操作碼:說明操作的性質和功能(e.g. 加減乘除、數據傳輸),長度有指令系統的指令條數決定(e.g. 256 條指令,則操作碼需要 8 位長度)。
操作數的地址:CPU 通過該地址讀取到所需要的操作數,可能是存儲器的地址,也可能是寄存器的地址。
操作結果的儲存地址:保存操作結果數據的地址。
下一條指令的地址:當程序順序執行時,下一條指令的地址又程序計數器(PC)給出,僅當改變程序的執行順序時(e.g. 跳轉、函數調用),下一條指令的支持才會有指令本身給出。
綜上,指令格式主要有 操作碼 和 地址碼 組成。需要注意的是,在指令字長較長的計算機中,操作碼的長度一般是固定的,并且由指令集的數量決定。但在指令字較短的計算機中,為了能夠充分利用指令字的位數,在有限的長度中實現更多的指令集數目,所以其操作碼長度被設計成是可變的,即把它們的操作碼在必要的時候擴充到地址碼字段。這就是所謂的 指令操作碼擴展技術。指令字的長度與 CPU 的位數密切相關。
指令類型
日常使用的 Intel CPU 大概有 2000 多條 CPU 指令。可以分為以下 5 大類型:
算術類指令:加減乘除。
數據傳輸類指令:變量賦值、讀寫內存數據。
邏輯類指令:與或非。
條件分支類指令:條件判斷語句。
無條件跳轉指令:方法、函數的調用跳轉。
繼續細分的話,具有如下指令類型:
算術邏輯運算指令
移位操作指令
算術移位
邏輯移位
循環移位
矢量運算指令(矩陣運算)
浮點運算指令
十進制運算指令
字符串處理指令
字符串傳送
字符串比較
字符串查詢
字符串轉換
數據傳輸指令
寄存器與寄存器傳輸
寄存器與主存儲器單元傳輸
存儲器單元與存儲器單元傳輸
數據交換(源操作數與目的操作下互換)
轉移指令
條件轉移
無條件轉移
過程調用與返回
陷阱
堆棧及堆棧操作指令
I/O 指令
特權指令
多處理機指令(在多處理器系統中保證共享數據的一致性等)
控制指令
指令尋址
指令尋址,即是根據指令字的地址碼來獲取到實際的數據,尋址的方式跟硬件關系密切,不同的計算機有不同的尋址方式。有的計算機尋址方式種類少,所以會直接在操作碼上表示尋址方式;有些計算機的尋址方式種類多,就會在指令字中添加一個特別用于標記尋址方式的字段,例如:假設該字段具有 3 位,那么就可以表示 8 種尋址方式。
NOTE:尋址方式與 CPU 內的寄存器設計密切相關。
直接尋址:指令字的地址碼直接給出了操作數在存儲器中的地址,是最簡單的尋址方式。
間接尋址:指令字的地址碼所指向的寄存器或存儲器的內容并不是真實的操作數,而是操作數的地址。間接尋址常用于跳轉指令,只要修改寄存器或存儲器的地址就可以實現跳轉到不同的操作數上。
相對尋址:把程序計數器(PC)的內容,即當前執行指令的地址與地址碼部分給出的偏移量(Disp)之和作為操作數的地址。這種尋址方式同樣常用于跳轉(轉移)指令,當程序執行到本條指令后,跳轉到 PC+Disp。
立即數尋址:即地址碼本身就是一個操作數的尋址方式,該方式的特點就是數據塊(因為實際上沒有尋址),但操作數固定。常用于為某個寄存器或存儲器單元賦初值,或提供一個常數。
通用寄存器尋址:CPU 中大概會有幾個到幾十個通用寄存器用于臨時儲存操作數、操作數的地址或中間結果,指令字的地址碼可以指向這些寄存器。通用寄存器具有地址短,存取速度快的特性,所以地址碼指向通用寄存器的指令的長度也會更短,節省存儲空間,執行效率更快。常被用于執行速度要求嚴格的指令中。
基址寄存器尋址:基址,即基礎地址,基址寄存器就是存放基址的寄存器,可以是一個專用寄存器,也可以使用通用寄存器來充當基址寄存器。執行指令時,需要將基址與指令字的地址碼結合得到完成的地址,此時的地址碼充當著偏移量(位移量)的角色。當存儲器容量較大時,直接尋址方式是無法存取到所有存儲單元的,所以通常會采用 分段 或 分頁 的內存管理方式。此時,段或頁的首地址就會存放于基址寄存器中,而指令字的地址碼就作為段或頁的長度,這樣只要修改基址寄存器的內容就可以訪問到存儲器的任意單元了。這種尋址方式常被用于為程序或數據分配存儲區,與虛擬地址實現密切相關。基址寄存器尋址方式解決了程序在存儲器中的定位存儲單元和擴大 CPU 尋址空間的問題。
變址寄存器尋址:變址寄存器內的地址與指令字地址之和得到了實際的有效地址,如果 CPU 中存在基址寄存器,那么就還得加上基址地址。這種尋址方式常用于處理需要循環執行的程序,例如:循環處理數組,此時變址寄存器所改變的就是數組的下標了。
堆棧尋址:堆棧是有若干個連續的存儲器單元組成的先進后出(FILO)存儲區。堆棧是用于提供操作數和保存運算結果的主要存儲區,同時還主要用于暫存中斷和子程序調用時的線程數據及返回地址。
通過 MIPS 感受指令字的設計
MIPS(Millions of Instructions Per Second)是一種最簡單的精簡指令集架構,由 MIPS 科技公司設計。MIPS 指令具有 32 位(最新版本為 64 位),高 6 位為操作碼(OPCODE),描述了指令的操作類型。其余 26 位具有 3 種格式:R、I 和 J。不同的指令類型和操作碼組合能夠完成多種功能實現,如下:
加法算數指令 add $t0,$s2,$s1 的指令字及其對應的機器碼如下:
opcode:0
rs:代表第一個寄存器 s1 的地址是 17
rt:代表第二個寄存器 s2 的地址是 18
rd:代表目標臨時寄存器 t0 的地址是 8
shamt:0,表示不位移
最終加法算數指令 add $t0,$s2,$s1 的二進制機器碼表示為 000000 10001 10010 01000 00000 1000000(0X02324020)。可以看見,機器碼中沒有保存任何實際的程序數據,而是保存了程序數據的儲存的地址,這也算是存儲程序計算機指令集設計的一大特點。
數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。