指令集架構 計算機也跟人類一樣,需要提供一套完整的語言讓人們跟它充分溝通,以完成正確的計算工作。 計算機語言最基本的單位是「指令」,集一部計算機所有指令所構成的集合,即稱為該計算機的指令集(instruction set)。
3.1 程式執行流程架構 計算機程式執行的流程圖與其階層架構
3.1 程式執行流程與階層架構 編譯期 載入期 執行期
3.1.1 編譯期 編譯期(compile time)又稱為編譯時間,是計算機程式從「人」的世界轉入「電腦」世界所經歷的第一個時期。 編譯器以高階語言的原始程式碼為其輸入,而輸出結果則為組合語言程式,或者是更進一步的目的程式(object program)。
3.1.1 編譯期 目的程式包含了以下三段記錄: 表頭記錄(header record):描述程式的名稱、起始位址及大小,起始位址通常由作業系統指派。 本文記錄(text record):程式的主體,以目的碼(object code)表示。 結尾記錄(end record):記錄程式執行時的起始位置。
3.1.1 編譯期 目的程式範例: 目的程式內容的範例,包含了表頭記錄、本文記錄、及結尾記錄。
3.1 程式執行流程與階層架構 編譯期 載入期 執行期
載入期(load time)亦稱載入時間,其包含了: 3.1.2 載入期 載入期(load time)亦稱載入時間,其包含了: 連結(linking) 載入(loading) 程式轉為目的碼之後,還不能算是一個可執行的程式。因為組合語言容許程式設計師將特定的複雜動作撰寫成一個個獨立的常式(subroutine),程式中需要這些動作的地方都可以呼叫對應的常式,以完成必須的運算 。
3.1.2 載入期 程式執行過程中,有些較低階的動作需要藉由系統所提供的更低階函式來完成,這些系統函式的集合稱為系統函式庫(system library)。不論是程式師所寫的常式、或是系統函式,本身都是一段小程式,所以在完成組譯程序之後,會被轉譯成一個個獨立的程式模組。這些已編譯好的程式模組必須經過連結的動作。 把常式所在的相對位址交給呼叫常式的指令,讓呼叫常式的指令知道要到哪裡去找到該常式的程式碼 。
3.1.2 載入期 負責這個連結動作的程式就稱為連結編輯器(linkage editor)或連結程式(linker)。 完成連結的程式充其量還只是可載入程式模組(load modules),尚無法立即運作。必須再以特定方式安排到記憶體中,才能交給CPU去執行,這個過程就稱為載入,負責載入的程式則稱為載入器或載入程式(loader)。
在載入記憶體之前,於編譯時間尚未解決的編譯問題都得一併處理: 3.1.2 載入期 在載入記憶體之前,於編譯時間尚未解決的編譯問題都得一併處理: 未定義的標籤(label)。 其他錯誤資訊。 為了減少程式在每次修改後都必須重新執行組譯、計算位址的動作,或是有加入外部引用(external references)的情況,需要如下的記錄,以提供程式再次定址的資訊 。 修正記錄(modification record) 包含需要重定位的指令位址、需要修改位址的長度 。
3.1.2 載入期 定義記錄(define record) 參考記錄(refer record) 3.1.2 載入期 定義記錄(define record) 記錄外部引用的相關資訊,以利於稍後的連結動作。 參考記錄(refer record) 記錄在外部引用時所使用的符號。 包含修正記錄、定義記錄、與參考記錄的目的程式
3.1 程式執行流程與階層架構 編譯期 載入期 執行期
3.1.3 執行期 執行期(execution time)是指令真正發揮功用的階段,程式完整載入記憶體之後,系統會「記得」程式起點的位址,而CPU就憑著這個位址,開始按照程式的邏輯流程,逐一去擷取正確位址中的機器指令來執行,直到程式結束。在這個過程中,每一個指令都會有自己的執行過程,或稱為指令週期(instruction cycle)。
3.2 指令的執行 執行指令的硬體架構 指令的執行週期
3.2.1 執行指令的硬體架構 執行指令的重要硬體: 主記憶體 CPU 快取(cache) 記憶體匯流排 執行指令的各重要硬體與其間之關係
3.2.1 執行指令的硬體架構 主記憶體 計算機程式的指令在完成載入之後,一開始都是儲存在主記憶體中,因此所有要執行的指令都是來自於記憶體。主記憶體一般是由一種稱為動態隨機存取記憶體(dynamic random access memory,DRAM)的半導體元件所組成,當它通上電源之後,可藉由電流來讀寫當中的值,並且維持資料內容不變;不過一旦失去電力,DRAM中的內容也就跟著消失。DRAM算是相當高速的儲存體,但是若跟CPU的運算速度相比,從主記憶體讀取一個指令的速度還是要比CPU執行一個指令慢上許多倍。
3.2.1 執行指令的硬體架構 CPU 真正負責執行指令的單元,它事實上就是由一堆不同功能的邏輯電路組成,主要組成份子有資料路徑(datapath)以及控制單元(control unit,CU)。前者包括用來執行指定運算的ALU及其他運算單元、還有存取速度堪與各運算單元相當的暫存器(register)等;後者則負責解釋(解碼)指令的意義、並控制執行的過程。
3.2.1 執行指令的硬體架構 快取(cache) CPU的運算速度相當高,並非一般DRAM的讀寫速度所能比擬,所以若要提高指令執行的速度,勢必要從改善記憶體存取速度的瓶頸著手。改善方法除了將主記憶體速度提昇之外,其實還可以加入一些容量較小、但速度較快速的記憶體來暫時儲存所要存取的指令或資料,這種介於主記憶體與CPU之間的記憶體就稱作快取(cache);它會先自主記憶體中複製一些可能即將被取用到的指令或資料區塊,當CPU要去擷取下一個指令來執行、或是要存取一筆資料時,可以優先到快取記憶體中找尋,藉以提升存取效能。
3.2.1 執行指令的硬體架構 記憶體匯流排 CPU的速度與主記憶體不同,為了確保能正確取得記憶體中的資料,通常CPU都是透過一種稱作匯流排(bus)的管道來存取記憶體。它其實就是一組橫跨在CPU與主記憶體之間的專屬傳輸管線,而且一般會將傳送資料與傳送記憶體位址的線路分開。匯流排與連接的裝置之間通常會有個介面(interface),這個介面上通常會有個暫存器以暫存傳送的資料,同時還會有些傳輸控制機制。
3.2 指令的執行 執行指令的硬體架構 指令的執行週期
3.2.2 指令的執行週期 一個指令的執行週期包含有四個階段: 取得指令 解碼指令 執行指令 儲存結果
3.2.2 指令的執行週期 取得指令: 當程式完成連結與載入之後,每個指令都會有自己專屬的指令位址。而在CPU中則有個特殊的程式計數器(program counter,簡稱PC)暫存器,專門用來儲存下一個要執行之指令的位址。 CPU根據程式計數器的內容,到記憶體的正確位址擷取(fetch)下一個要執行的指令,並經資料匯流排(data bus)將指令傳回、存入CPU內部一個特殊的指令暫存器(instruction register,簡稱IR)中來執行。
3.2.2 指令的執行週期 程式若是按照記憶體位址循序執行,則每次執行完後,會將PC暫存器的內容自動加1,以對映到(或稱指到)下一個指令所在的位址;但假使有不按照位址順序執行的情況,例如遇到分支(branch)指令時,便會直接將下一個要執行指令的正確位址儲存到PC暫存器。
3.2.2 指令的執行週期 解碼指令 當IR內的機器語言指令傳回CPU之後,最重要的動作就是去解讀它,這個步驟稱為解碼(decode)。 3.2.2 指令的執行週期 解碼指令 當IR內的機器語言指令傳回CPU之後,最重要的動作就是去解讀它,這個步驟稱為解碼(decode)。 每一個機器指令都會表明它所要執行的動作、以及參與這個動作的所有資料,前者稱為指令中的運算子(operator)、後者則稱為運算元(operand)。 對映到指令碼,則代表動作的部分稱為運算碼(operation code,簡稱op_code),剩餘的碼則用來指示資料的所在。
3.2.2 指令的執行週期 CPU會先根據運算碼內容,來決定該如何取得運算元或其位址。由於每個機器碼都代表唯一的一種運算,所以在程式編(組)譯的過程必須先經由編碼(coding)的程序,將組合語言指令依照既定的編碼規則轉換為唯一的二進制碼。 當指令要執行時,則必須將這個二進制的機器碼解讀並拆解出運算子,然後根據運算子的定義與剩餘的指令碼內容,找出要參與運算的運算元值。
3.2.2 指令的執行週期 執行指令 指令經過解碼之後,CPU會進一步去取得所需要的運算元,並將它們放到正確的暫存器中。等所有運算元都取出且就位之後,便會將資料送入資料路徑,並透過控制電路,啟動指令所指定的運算單元來完成運算。
3.2.2 指令的執行週期 儲存結果 算後所得的結果必須要儲存到正確的位置,指令才算完成。這個位置也是要根據前述解碼後的結果來決定,可能是某個暫存器、或是根據運算元內容所推算而得的某個記憶體位址。在許多以暫存器來儲存執行結果的計算機上,『儲存結果』未必會成為獨立的執行階段,它可能在執行階段完成時便已存入暫存器或記憶體中。不過將運算結果存入主記憶體的動作,有時也可能為另一個獨立的指令。
運算子就是指令的代碼,用來指定要執行哪一種運算。 3.3 指令的格式 運算子就是指令的代碼,用來指定要執行哪一種運算。 運算元所表示的意義則不固定: 暫存器的代號、記憶體位址 、實際的資料內容。 指令格式會依硬體設計或指令類型的不同而有所變化 。
3.3 指令的格式 四位址指令(Four-Address Instruction) 三位址指令(Three-Address Instruction) 雙位址指令(Two-Address Instruction) 單位址指令(One-Address Instruction) 零位址指令(Zero-Address Instruction)
3.3.1 四位址指令(Four-Address Instruction) op_code:運算碼 address 1:輸出運算元的定址 address 2:第一個輸入運算元的定址 address 3:第二個輸入運算元的定址 next instruction address:下一道要執行之指令的位址
3.3.1 四位址指令(Four-Address Instruction) 若指令集利用四位址方式編碼,則不需使用到程式計數器(program counter,PC): 下一道指令的位址會存在目前的指令之中。 使得其長度較長。 若撰寫相同功能的程式,四位址格式所需的指令個數最少。
3.3 指令的格式 四位址指令(Four-Address Instruction) 三位址指令(Three-Address Instruction) 雙位址指令(Two-Address Instruction) 單位址指令(One-Address Instruction) 零位址指令(Zero-Address Instruction)
3.3.2 三位址指令(Three-Address Instruction) op_code:運算碼 address 1:輸出運算元的定址 address 2:第一個輸入運算元的定址 address 3:第二個輸入運算元的定址
3.3.2 三位址指令(Three-Address Instruction) 以三位址方式編碼,則需要PC來決定執行的順序。 優點: 指令長度較四位址格式短、容易理解、高程式的可讀性(readability)高。
3.3.2 三位址指令(Three-Address Instruction) 例:假設我們要計算下面的乘法式子 A = B ×C 其中B是被乘數、C是乘數、A是積。只要用三位址的方式就可以得到兩數相乘的結果: MUL A, B, C ;A B * C
3.3.2 三位址指令(Three-Address Instruction) 假使每個暫存器代號的編碼長度為3,若三組暫存器的代號分別為A:001、B:010、C:011,而乘法指令的運算碼為0011,則上述指令便可翻譯成如下16位元的三位址格式:
3.3 指令的格式 四位址指令(Four-Address Instruction) 三位址指令(Three-Address Instruction) 雙位址指令(Two-Address Instruction) 單位址指令(One-Address Instruction) 零位址指令(Zero-Address Instruction)
3.3.3 雙位址指令(Two-Address Instruction) op_code: 運算碼 address 1:第一個輸入兼輸出運算元的定址 address 2:第二個輸入運算元的定址
3.3.3 雙位址指令(Two-Address Instruction) 雙位址的指令長度較四位址、三位址短 ,且其下一指令的位址同樣需要由PC來決定。 例:假設我們要計算下面的乘法式子 A = B ×C 若直接用雙位址格式的指令來運算 MUL A, B ;A A * B 完成相乘後的積會被存入A中。這樣一來原本A中的值即會被覆蓋過去。
3.3.3 雙位址指令(Two-Address Instruction) MOV C, A ;C A MUL C, B ;C C * B 如此一來C就會是A和B相乘之後的積,而A暫存器的內容也不會受到更改。
3.3 指令的格式 四位址指令(Four-Address Instruction) 三位址指令(Three-Address Instruction) 雙位址指令(Two-Address Instruction) 單位址指令(One-Address Instruction) 零位址指令(Zero-Address Instruction)
3.3.4 單位址指令(One-Address Instruction) op_code:運算碼 address :輸入運算元的定址
3.3.4 單位址指令(One-Address Instruction) 單位址指令應付兩個輸入的運算時,需利用特定的累加器(accumulator,AC)來當作工作區,用來取代前述二位址指令中的第一個運算元,它不僅提供另一個輸入來源,也當成儲存運算結果的目的地。 AC本身也是一個暫存器,它的長度會配合運算所需,而且程式師也無法自行指定其他暫存器來取代它。
3.3.4 單位址指令(One-Address Instruction) 可將單位址的格式想成兩位址的格式,只是運算元的第一個欄位被「隱藏」起來,而以AC來取代該位址的角色:
3.3.4 單位址指令(One-Address Instruction) 例:下面是兩個以雙位址表示的算術指令 ADD B, C ;B B + C SUB A, B ;A A - B 若利用單位址格式來表示上述兩個指令,則: LOAD B ;AC B ADD C ;AC AC + C STOR B ;B AC LOAD A ;AC A SUB B ;ACAC - B STOR A ;A AC
3.3 指令的格式 四位址指令(Four-Address Instruction) 三位址指令(Three-Address Instruction) 雙位址指令(Two-Address Instruction) 單位址指令(One-Address Instruction) 零位址指令(Zero-Address Instruction)
3.3.5 零位址指令(Zero-Address Instruction) op_code:運算碼
3.3.5 零位址指令(Zero-Address Instruction) 零位址指令的本身就是op_code,省略了所有的運算元;但並非所有的指令都能以此種格式表示。 零位址指令以一種稱為堆疊(stack)的資料結構來輔助算術或邏輯的運算。 堆疊結構: 後進先出(Last-In-First-Out,LIFO)的儲存空間。 資料只能由上端放入跟取出。
3.3.5 零位址指令(Zero-Address Instruction) 運算元的資料結構是以堆疊方式構成,則除了指令只以零位址的格式來表示之外,還需要兩個單位址的指令: 存入堆疊指令(PUSH) PUSH X ;將X存入堆疊頂端 取出堆疊指令(POP) POP X ;將堆疊頂端的元素取出,放入X中
3.3.5 零位址指令(Zero-Address Instruction) 堆疊結構圖 堆疊操作過程實例
3.3.5 零位址指令(Zero-Address Instruction) 利用堆疊架構計算一個運算式時,必須以後置式表示法(postfix notation)表示其運算式 : 運算子必須放在所對應運算元的後面。 例: 中置式表示法呈現的式子: A + B × C 換成後置式表示法: A B C × +
3.3.5 零位址指令(Zero-Address Instruction) (a)一般的中置式表示法 (b)以後置式表示法的堆疊輸入順序,由左到右(c)以前置式表示法的堆疊輸入順序,由右到左
3.3 指令的格式 【例題】設有一運算式如下 Y = ( A – B ) ÷ ( C + D * E ) 試分別以前述的四位址、三位址、雙位址、單位址與零位址之指令格式表示。其中加、減、乘、除運算子分別為ADD、SUB、MUL、DIV;另有存入特定位址(STORE)與自特定位址載入(LOAD)兩個指令。
四位址: 3.3 指令的格式 【解答】 I1: SUB R1, A, B, I2 ;R1 A – B 3.3 指令的格式 【解答】 四位址: I1: SUB R1, A, B, I2 ;R1 A – B I2: MUL R2, D, E, I3 ;R2 D * E I3: ADD R3, C, R2, I4 ;R3 C + R2 I4: DIV Y, R1, R3, I5 ;Y R1 ÷ R3
三位址: SUB R1, A, B ;R1 A – B 3.3 指令的格式 【解答】 MUL R2, D, E ;R2 D * E 3.3 指令的格式 【解答】 三位址: SUB R1, A, B ;R1 A – B MUL R2, D, E ;R2 D * E ADD R3, C, R2 ;R3 C + R2 DIV Y, R1, R3 ;Y R1 ÷ R3
SUB A, B ;A A – B 雙位址: 3.3 指令的格式 【解答】 MUL D, E ;D D * E 3.3 指令的格式 【解答】 雙位址: SUB A, B ;A A – B MUL D, E ;D D * E ADD C, D ;C C + D DIV A, C ;A A ÷ C MOV Y, A ;Y A
3.3 指令的格式 【解答】 SUB B ;AC AC – B STORE R1 ;R1 AC LOAD D ;AC D 3.3 指令的格式 【解答】 單位址: LOAD A ;AC A SUB B ;AC AC – B STORE R1 ;R1 AC LOAD D ;AC D MUL E ;AC AC * E ADD C ;ACAC + C STORE R2 ;R2 AC LAOD R1 ;AC R1 DIV R2 ;AC AC ÷ R2 STORE Y ;Y AC
3.3 指令的格式 【解答】 先將 (A–B)÷(C+D*E) 轉為後置式 AB–CDE*+÷ 堆疊內容 PUSH A A 3.3 指令的格式 【解答】 零位址: 先將 (A–B)÷(C+D*E) 轉為後置式 AB–CDE*+÷ 堆疊內容 PUSH A A PUSH B A B SUB R1 ;R1 A – B PUSH C R1C PUSH D R1CD PUSH E R1CDE MUL R1CR2 ;R2 D * E ADD R1R3 ;R3 C * R2 DIV R4 ;R4 R1 ÷ R3 POP Y ;Y R4
3.4 資料定址模式 定址法(addressing) 3.4 資料定址模式 定址法(addressing) 是用來決定計算機如何取得指令運算元的方法,也是取得運算元之有效位址(efficient address,EA)的方法。
3.4 資料定址模式 立即定址法(Immediate Addressing) 直接定址法(Direct Addressing) 間接定址法(Indirect Addressing) 暫存器定址法(Register Addressing) 暫存器間接定址法(Register Indirect Addressing) 位移型定址法(Displacement Addressing) 隱含型定址法(Implicit Addressing)
3.4.1 立即定址法(Immediate Addressing) 資料的值就在指令當中,提取運算元之後便能「立即」取得資料,不用再存取記憶體。 優點:執行速度較快 缺點:資料的數值範圍會受到運算元欄位長度限制。 MOV X, 1010 ; 將1010這個值存入暫存器變數X中 立即定址法,假設運算元A=1010,提取完運算元後可以立即得到資料
3.4 資料定址模式 立即定址法(Immediate Addressing) 直接定址法(Direct Addressing) 間接定址法(Indirect Addressing) 暫存器定址法(Register Addressing) 暫存器間接定址法(Register Indirect Addressing) 位移型定址法(Displacement Addressing) 隱含型定址法(Implicit Addressing)
3.4.2 直接定址法(Direct Addressing) 屬於簡易的定址模式,運算元所指的位址內即是資料。 優點:只需一次記憶體存取就可以得到資料。 缺點:受限於指令位址欄位的長度,能定址的範圍非常有限。 MOV X, [1010] ;將記憶體位址1010中的值存入暫存器變數X中 採用直接定址法,運算元的資料即是有效位址EA=A,此例的值為A000h,存取到該記憶體位址後可取得真正的資料值1010
3.4 資料定址模式 立即定址法(Immediate Addressing) 直接定址法(Direct Addressing) 間接定址法(Indirect Addressing) 暫存器定址法(Register Addressing) 暫存器間接定址法(Register Indirect Addressing) 位移型定址法(Displacement Addressing) 隱含型定址法(Implicit Addressing)
3.4.3 間接定址法(Indirect Addressing) 間接法定址的指令,其運算元的真正有效位址儲存在記憶體之中。 由指令的運算元欄位得到存放有效位址的記憶體位址後,必須再對記憶體進行一次存取,才能取得有效位址;之後再到有效位址去取得其內容值,才是真正的運算元資料,此過程需要進行兩次記憶體存取。 優點:運算元的有效位址是儲存在記憶體 ,定址範圍可增大。 缺點:增加指令的執行時間。
3.4.3 間接定址法(Indirect Addressing) MOV X, A; 先以運算元欄位A中所存的值為記憶體位址,到其中取出有效位址,再到該有效位址中取出數值,並存入暫存器變數X 採用間接定址法,若從運算元欄位中取得的值為A=A000h,此時必須先以A為位址到記憶體中對應的位置取得有效位址EA=B000h,再根據此EA取得真正用來運算的資料1010;因此可知EA=(A)
3.4 資料定址模式 立即定址法(Immediate Addressing) 直接定址法(Direct Addressing) 間接定址法(Indirect Addressing) 暫存器定址法(Register Addressing) 暫存器間接定址法(Register Indirect Addressing) 位移型定址法(Displacement Addressing) 隱含型定址法(Implicit Addressing)
3.4.4 暫存器定址法(Register Addressing) 類似直接定址法,暫存器定址法一樣是利用運算元欄位來指定資料所在位置,但不同的是它所指定的位置是暫存器。 優點:從暫存器存取資料,速度快。 缺點:暫存器的個數有限,指令所形成的程式會因暫存器個數而受限。 MOV X, R ;先從運算元欄位R所指的暫存器中取出數值,再存入暫存器變數X 採用暫存器定址法,運算元欄位所指的暫存器內容即為資料,如此處EA=R,而真正的運算元值為1010
3.4.5 暫存器間接定址法(Register Indirect Addressing) 有效位址是儲存在運算元欄位所指定的暫存器中,因此必須先根據運算元欄位,從對應的暫存器中取出資料之有效位址,再利用該有效位址到記憶體去抓取資料。 兩次的存取動作才能得到真正的運算元資料,只不過一次是對暫存器、另一次是對記憶體。 優點:字組寬之定址能力 、加快取得有效位址的速度。 缺點:需要額外的記憶體存取。
3.4.5 暫存器間接定址法(Register Indirect Addressing) MOV X, [R]; 先從運算元欄位R所指的暫存器中取出有效位址,再到該有效位址的記憶體位置中取出數值,並存入暫存器變數X 採用暫存器定址法,運算元欄位所指的暫存器內容即為資料,如此處EA=R,而真正的運算元值為1010
3.4 資料定址模式 立即定址法(Immediate Addressing) 直接定址法(Direct Addressing) 間接定址法(Indirect Addressing) 暫存器定址法(Register Addressing) 暫存器間接定址法(Register Indirect Addressing) 位移型定址法(Displacement Addressing) 隱含型定址法(Implicit Addressing)
3.4.6 位移型定址法(Displacement Addressing) 將一個基底位址(base address)加上位移量(displacement)以獲得「真正的有效位址」。 基底位址可以是: 一個暫存器的值。 一個運算元的內容。 位移量則是真正的有效位址相對於基底位址之間的差距。
3.4.6 位移型定址法(Displacement Addressing) 位移型定址法可細分成三種: 相對定址法(relative addressing) 基底定址法(base-register addressing) 索引法(indexing) 位移型定址法概念圖
3.4.6 位移型定址法(Displacement Addressing) 相對定址法(Relative Addressing) 主要是用於分支(branch)或跳躍(jump)指令。 程式因判斷或條件而產生分支時,PC值必須重新給定,其方法就是將指令的「實際有效位址相對於PC的位移量」透過運算元欄位提供給電腦,用以更改PC的內容。 EA=(PC)+運算元內容 採用相對定址法的指令只需使用一個運算元即能找到EA、並對記憶體進行存取,但定址能力會被運算元欄位長度所限制。
3.4.6 位移型定址法(Displacement Addressing) 相對定址法
3.4.6 位移型定址法(Displacement Addressing) 基底定址法(Base-Register Addressing) 當程式需對較多鄰近資料(例如陣列資料結構)同時做位址修正的處理,採用基底定址法來存取資料就會非常方便。 程式或資料片段的起始位址當做基底位址,並將它存入指定的暫存器中;而該程式或資料片段中的記憶體位址則都是相對於起始位址的位移量。 獲得EA的方式為: 基底+運算元中的位移量 利用基底定址法可做到可再定位(relocatable)程式。
3.4.6 位移型定址法(Displacement Addressing) 基底定址法
3.4.6 位移型定址法(Displacement Addressing) 索引法(Indexing) 類似於基底定址法,不同點只是「起始位址」與「位移」儲存的位置剛好相反。 「起始位址」存在指令的運算欄。 「位移」存在暫存器。 有效位址計算方式為: 運算元內容+暫存器內容 由於位移是存在暫存器之中,所以可以透過遞增指令(如INC)自動地改變位移的量,適合用在陣列的存取。
3.4.6 位移型定址法(Displacement Addressing) 索引法
3.4.6 位移型定址法(Displacement Addressing) 【例題】 請說明「基底定址法」與「索引法」之異同。
3.4.6 位移型定址法(Displacement Addressing) 【解答】 相同 (1) EA的計算方法; EA = (R) + (operand); (2) 適用於處理陣列或其他連續空間的資料結構。 相異 (1) 基底定址法的暫存器儲存起始位址、運算元儲存位移量;索引法則相反,其位移量在暫存器、起始位址在運算元; (2) 基底定址法的暫存器內含值不能用指令來更改,索引法則可用指令更改暫存器內含值(如INC、DEC指令)。
3.4 資料定址模式 立即定址法(Immediate Addressing) 直接定址法(Direct Addressing) 間接定址法(Indirect Addressing) 暫存器定址法(Register Addressing) 暫存器間接定址法(Register Indirect Addressing) 位移型定址法(Displacement Addressing) 隱含型定址法(Implicit Addressing)
3.4.7 隱含型定址法(Implicit Addressing) 隱含型定址法常見於單一運算元格式的指令。 許多運算都需要有兩個輸入運算元與一個輸出運算元,通常預設會以一個AX暫存器(累加器)來當作被乘數,同時也當作輸出的對象,因此不需要在指令中特別指定。 MUL BX; 將AX與BX暫存器的值相乘,並將結果存到AX暫存器中。
3.4 資料定址模式 定址模式 有效位址 記憶體 存取次數 優缺點 立即定址法 Operand=A 0次 直接定址法 EA=A 1次 3.4 資料定址模式 定址模式 有效位址 記憶體 存取次數 優缺點 立即定址法 Operand=A 0次 優:不需記憶體存取,速度快 缺:運算元大小受到暫存器個數所限制 直接定址法 EA=A 1次 優:較為簡單 缺:位址空間受到限制 間接定址法 EA=(A) 2次 優:擁有較多的位址空間 缺:多次記憶體存取,速度慢 暫存器定址法 EA=R 缺:位址空間受暫存器個數所限制
3.4 資料定址模式 定址模式 有效位址 記憶體 存取次數 優缺點 暫存器間接定址法 EA=(R) 1次 優:擁有較多的位址空間 3.4 資料定址模式 定址模式 有效位址 記憶體 存取次數 優缺點 暫存器間接定址法 EA=(R) 1次 優:擁有較多的位址空間 缺:需要額外的記憶體存取 位移型定址法 EA=A+(R) 優:定址能力較有彈性 缺:EA的取得需要計算 隱含型定址法 EA=預設暫存器 0次 優:速度快,節省指令長度 缺:需搭配特定暫存器
3.5 指令集的設計與考量 指令集的完備性 指令集的最適化
完整通用型計算機通常需具備的六大類指令: 3.5.1 指令集的完備性 完整通用型計算機通常需具備的六大類指令: 資料轉移指令 算術、邏輯、以及比較指令 分支指令 輸出/輸入指令 浮點運算指令 特殊系統呼叫指令
3.5.1 指令集的完備性 資料轉移指令 計算機處理的主要是資料,資料在程式執行的過程中必須在暫存器與記憶體之間搬移或複製,因此任何指令集都一定要有此類指令。 常見的如: MOV、LDW(load word)、STW(store word)、LDB(load byte)、STB(store byte) 有了這些移轉指令,計算機就能順利地自記憶體取出資料來運算,也可以將運算結果存回指定的記憶體空間。
3.5.1 指令集的完備性 算術、邏輯、以及比較指令 計算機最強大的功能就是數值與邏輯運算,因此這一類的指令必定不可或缺。 3.5.1 指令集的完備性 算術、邏輯、以及比較指令 計算機最強大的功能就是數值與邏輯運算,因此這一類的指令必定不可或缺。 此處所指的數值運算以整數運算為首要,因為它是所有算術運算的基礎,而且硬體線路也比較容易實現。 算術運算: 加(ADD)、減(SUB)、乘(MUL)、除(DIV),還有取相反數(即取二的補數) 邏輯運算: AND、OR、NOT 、XOR、XAND
3.5.1 指令集的完備性 比較運算: 有了這些算術、邏輯、以及比較指令 ,計算機就能完成各種數值與邏輯的運算。 3.5.1 指令集的完備性 比較運算: COMP:根據兩個輸入值的大小來設定某個特定暫存器或旗標(flag)的值。 有了這些算術、邏輯、以及比較指令 ,計算機就能完成各種數值與邏輯的運算。
3.5.1 指令集的完備性 分支指令 通常分為 條件分支:一般常見的BRANCH指令。 3.5.1 指令集的完備性 分支指令 通常分為 條件分支:一般常見的BRANCH指令。 BRZ(branch on zero)指令,就會根據先前的比較運算或算術運算結果是否為0,來決定下一個要執行的指令位址。 無條件分支:又稱為跳躍(jump),當程式執行到這一道指令時,便會根據該指令的參數來決定下一個要執行指令的位址。
3.5.1 指令集的完備性 輸出/輸入指令 計算機一定要能從外界讀入資料,並將處理完成的資料「展現」出來,才能發揮用途。 3.5.1 指令集的完備性 輸出/輸入指令 計算機一定要能從外界讀入資料,並將處理完成的資料「展現」出來,才能發揮用途。 輸出/入指令就是這樣的一系列指令,它可以讓CPU從周邊裝置將資料讀進記憶體或CPU中,也可以將資料送到各種輸出/入裝置之上。此類指令的格式受周邊定址方式所影響。
3.5.1 指令集的完備性 浮點運算指令 浮點運算是複雜度較整數更高的一種數值運算,在實際的應用中,數值的範圍原本就相當大,而運用浮點數即可以讓計算機更輕易地滿足此類需求。 其實只要有完整的整數運算能力,即可用程式來完成各種浮點運算,只不過效能並不理想,尤其面對需要大量浮點運算的應用時,更會形成嚴重的瓶頸。假使計算機能以硬體提供浮點運算指令,將可大幅提升數值運算的效能,使得計算機的能力更加強大。 常見的浮點運算指令: 加(ADD)、減(SUB)、乘(MUL)、除(DIV)、開根號(SQRT)、對數運算(LOG)
3.5.1 指令集的完備性 特殊系統呼叫指令 這類指令通常與微處理器本身的設計有關,有些微處理器會提供一些特殊功能,例如關閉計算機、進行中斷服務等,這些都可利用這類系統呼叫指令來使用,而其所提供的指令也都因處理器設計目標與理念而各不相同。
3.5 指令集的設計與考量 指令集的完備性 指令集的最適化
設計計算機處理器時最重要、也最難抉擇的課題 : 3.5.2 指令集的最適化 設計計算機處理器時最重要、也最難抉擇的課題 : 找出一套最恰當或最適化(optimal)的指令集 。 常見的議題: 指令的數量 指令的格式 - 運算元的多寡 定址模式
3.5.2 指令集的最適化 指令的數量 指令的數量會影響到程式執行的效能,也會影響計算機的硬體設計。 3.5.2 指令集的最適化 指令的數量 指令的數量會影響到程式執行的效能,也會影響計算機的硬體設計。 通常計算機除了具有完備性的基本指令集之外,還會針對部分常用的運算提供一些額外的指令,如此一來,許多原本需要由多個指令組合而成的動作,現在只需要用一兩個指令就可處理完畢,效能自然提高了。 但是如果加入了太多的專用指令,則會造成處理器上的元件數量急遽膨脹,不僅提高了設計上的困難度,而且還會影響單一指令的執行效能。
3.5.2 指令集的最適化 指令的格式 - 運算元的多寡 指令的格式對硬體設計有相當的影響。 3.5.2 指令集的最適化 指令的格式 - 運算元的多寡 指令的格式對硬體設計有相當的影響。 指令所能提供的運算元越多,使用的彈性當然越大,因為可以在一個指令中完成更多的事。 運算元較少,指令長度可以縮短,取得運算資料或回存結果的動作亦可較制式化,單一指令的執行速度可以提高。
3.5.2 指令集的最適化 定址模式 參與運算的資料都來自暫存器,指令運算速度快。 3.5.2 指令集的最適化 定址模式 參與運算的資料都來自暫存器,指令運算速度快。 RISC的指令中的運算元。 暫存器與記憶體之間的資料轉移由載入(load)與儲存(store)指令來負責,稱為載入/儲存模式(load/store mode)。 若單一指令的資料來源為記憶體,那麼在一個指令週期中,可能會有一到多次的記憶體存取動作,太過多樣化的執行流程將會大幅增加硬體設計的複雜程度。
3.6 指令的編碼與解碼 固定式編碼(Fixed Encoding) 混合式編碼(Hybrid Encoding) 變動長度編碼(Variable Length Encoding)
3.6.1 固定式編碼(Fixed Encoding) 不同格式的指令都擁有相同長度的運算碼,即運算碼的位元數皆為固定,且長度只與指令總數有關。 指令格式 編號 指令代碼 零位址 00 000000 ~ 04 000100 一位址 05 000101 16 010000 二位址 17 010001 40 101000 未使用 41 101001 63 111111 固定式編碼的指令集
3.6.1 固定式編碼(Fixed Encoding) 優點: 軟、硬體設計較為簡單。 編譯階段只要先建好指令碼的對照表,再利用簡單的查表法,即可將運算碼轉成二進位的op_code。 解碼時,則只需取出固定長度的op_code送入解碼線路。 缺點: 會有未使用到的編碼空間,而造成浪費。
3.6 指令的編碼與解碼 固定式編碼(Fixed Encoding) 混合式編碼(Hybrid Encoding) 變動長度編碼(Variable Length Encoding)
3.6.2 混合式編碼(Hybrid Encoding) 混合不同長度之運算碼的編碼方式,它會根據「指令格式」的不同而調整「運算碼欄位」的位元數。 例: 指令集包含了雙位址、單位址、及零位址格式的指令,則可能的編碼方式如下: 指令格式 欄位 零位址 單位址 雙位址
3.6.2 混合式編碼(Hybrid Encoding) 指令格式 編號 指令代碼 雙位址 00 addr1 addr2 01 1 ... 22 23 單位址 96 97 106 107 Addr2 零位址 432 433 436 混合式編碼的指令集
3.6.2 混合式編碼(Hybrid Encoding) 優點: 減少「運算碼欄位」固定占用的位元數 ,可提供較多位元給雙位元格式的指令運算元使用。 對於單位址及零位址的指令,由於需要的「運算元欄位」相對較少,因此可將沒有用到的運算元欄位也納入編碼的範圍,以獲得額外的編碼空間。 缺點: 解碼程序複雜許多。 若針對op_code的最大可能長度來設計解碼線路,則線路複雜度大。
3.6 指令的編碼與解碼 固定式編碼(Fixed Encoding) 混合式編碼(Hybrid Encoding) 變動長度編碼(Variable Length Encoding)
3.6.3 變動長度編碼(Variable Length Encoding) 指令長度與運算碼長度皆可變動的指令編碼方式,可提供最大的彈性,並可隨時以不同長度的指令來擴充或延伸其指令集。 Intel 80x86的IA-32指令集。 幾種不同的典型IA-32指令: a. JE EIP + 位數量 4 8 JE 跳躍條件 位移量 (Displacement)
3.6.3 變動長度編碼(Variable Length Encoding) b. CALL 8 32 CALL 差距值 (Offset) c. MOV EBX, [EDI+45] 6 1 8 MOV d w r/m 後置位元組 (Postbyte) 位移量 (Displacement)