# 計算機組織 ISA 來源: 清大開放課程 - [影片](https://ocw.nthu.edu.tw/ocw/index.php?page=chapter&cid=76&chid=3086) - [影片5](https://ocw.nthu.edu.tw/ocw/index.php?page=chapter&cid=76&chid=3087) - [影片6](https://ocw.nthu.edu.tw/ocw/index.php?page=chapter&cid=76&chid=3088) - [簡報](https://view.officeapps.live.com/op/view.aspx?src=https%3A%2F%2Focw.nthu.edu.tw%2Focw%2Fupload%2F76%2F802%2FInstruction%2520Set%2520Architecture.ppt&wdOrigin=BROWSELINK) --- ![image](https://hackmd.io/_uploads/BJtCbGrbye.png) ![image](https://hackmd.io/_uploads/rkQWXGrbke.png) ## ISA - RISC指令一定是32bit長 (方便hardware優化) - CISC指令長度不固定。 - Simplcity favors regulartiy - RISC的Operands只能從register拿,CISC可以從Register,memory拿。 - Register有助於提升Code density: - 用更少的bit描述位址。 - Smaller is faster. - 在計算機組織中,「越小越快」(Smaller is faster)這個概念主要源於以下幾個原因: - **距離縮短**:在處理器內部,訊號需要在不同的元件之間傳遞。當元件的尺寸變小時,訊號傳遞的距離也會縮短,從而減少延遲,提升速度。 - **功耗降低**:較小的元件通常消耗較少的電能,這不僅有助於降低功耗,還能減少發熱,進一步提升系統的穩定性和性能。 - **更高的集成度**:較小的元件可以在同樣的晶片面積上集成更多的功能,這意味著可以在更小的空間內實現更高的計算能力。 - **提升頻率**:較小的元件可以更容易地提升工作頻率,從而提高處理器的運算速度。 ![image](https://hackmd.io/_uploads/rJC4FfHbke.png) - r2,r3 : percedual code使用(如sub routine) ![image](https://hackmd.io/_uploads/SkdHcMrbyx.png) - Float 的計算由FPU負責。 ## Register ### Accmulator: 以前只有一個register,只能存Main memory讀取資料後,把處理結果放在累加器裡。 ### Stack Last in first out. ### Register ![image](https://hackmd.io/_uploads/Bkua-orWkx.png) - Instruction數量多不一定慢,要考慮cycle per instruction。 - Number of instruction - Register (reg-mem): - 缺點是每個instruction很長(因為mem的位址很長) - Accumulator - 缺點是Add很快,但Load很慢 ## Memory - byte-address: - MIPS至少$2^{32}$個bytes :arrow_forward: 地址要用32個bits。 - Word-address - Memory的基本單位。 ```bash g=A[8] lw $to 32($s3) #$t0 gets A[8] ``` - Memory access: - 先找到memory pointer register(32bits),再計算位移(offset in **byte**)到指定位址。 - 範例``` lw $t0 offset($pointer) ```,則只需要5bits的register就能描述位址。 - 通常offset是+4(因為1個word是4bytes) - Little endian: - 讀取word裡面的byte的順序從0,1,2,3... - Big endian: - 讀取word裡面的byte的順序從3,2,1,0.. - Constant - 能直接寫在Instruction。 (不用lw) - 分析後有接近50%的code屬於跟常數互動 :arrow_right: Make the common case fast - Constant instruction 範例 ```c addi $s1 $s1 4 # A = A+4 slti ... andi ... ori ... ``` - 0的register是直接hardwire設定的。 ```C add $s2 $s1 $zero # 0 也可用於搬運變數 ``` ## Instruction type - MIPS (RISC)只有3種Instruction format,但x86有很多種(CISC) - format越少,硬體處理的overhead越少。 ### R-Type - 負責算術運算,邏輯運算... |6 bit|5 bit|5 bit|5 bit|5 bit|6 bit| |---|---|---|---|---|---| |opcode | dst reg| src reg |src reg |shamt | funct | - op code: 000000區分它屬於R-type - funct : 區分實際作用(加,減,and,or...) - shamt : shift amount. (因為data只有32bit,用5個bit即可表示。) #### 範例 ![image](https://hackmd.io/_uploads/rJbsDxDZJl.png) #### Bitwise operation ![image](https://hackmd.io/_uploads/B19zd4db1x.png) 範例 ``` sll $t2 $s0 4 ``` - sll:shift left並補0。 - srl:shift right並補0。 - sra:shift right,用sign extending補 (正數補0、負數補1)。 ![image](https://hackmd.io/_uploads/B1myY4uW1g.png) - shift operation很快,聰明的compiler會把乘除法替換成shift operation。 #### 其他operation ```c and $t2 $s0 $s1 or $t2 $s0 $s1 nor $t2 $s0 $zero # not operation ``` --- ### I-Type - 牽扯Immediate的運算。 |6 bit|5 bit|5 bit|16bit| |---|---|---|---| |opcode | src reg| dst reg | immediate | - 16 bit的immediate能表示$2^{16}$個數字。 - immediate - signed number. - 實際做運算時要擴充到32bits (addi,slti的immediate **sign-extended to 32 bits.**) - sign-extended - 第一個bit擺正負號,其他擴充出來的bit: - 正:補0 - 負:補1 - 雖然src,dst register的內容指向32 bits的數值,但跟immediate的運算受限於16bits.(constant range: +-$2^{15}$) #### 範例 ```c addi $t2 $t1 -50 ``` - 注意組語固定左邊放目標register: - $t2 : 目標寫入的register - $t1 : operand ##### lw/sw是I-type instruction ```c lw $t0 1200($t1) # $t0是destination,$t1讀到$t0 sw $t0 1200($t1) # $t0是source, 寫到$t1 ``` - offset範圍受限於+-$2^{15}$. #### Branch * 注意branch是 **I-type** instruction. * 能跳的範圍受限於+-$2^{15}$. Conditional jump ```bash beq reg1 reg2 L1 #if(reg1==reg2) goto L1 bne reg1 reg2 L1 #if(reg1!=reg2) goto L1 ``` 範例: 編譯 ```clike= if(i==j) {f=g+h;} else {f=g-h;} ``` ```bash= bne $s3 $s4 Else # if(i!=j) goto else add $s0 $s1 $s2 # f=g+h j Exit # 跳出 Else: sub $s0 $s1 $s2 # f=g-h Exit: ``` --- ```clike= while (a[i]==k) {i+=1;} ``` * 假設a為int array存在\$s6, i在\$t1 ```bash= Loop: sll $t1 $s3 2 #t1=i*4 因為每個element 4bytes長 add $t1 $t1 $s6 #第a[i]個element位址 lw $t0 0($t1) #存memory讀a[i]到register bne $t0 $s5 Exit # if(a[i] !=k ) goto Exit addi $s3 $s3 1 # i=i+1 j Loop Exit: ... ``` #### 大於,小於怎麼做 **slt** : Set on less than ```bash slt rd rs rt #if(rs < rt) rd=1 ; else rd =0; ``` 範例 ```bash # if(g<h) goto less; slt $t0 $s0 $s1 #t0=1 if s0 < s1 bne $t0 $0 Less # if(t0!=0) goto Less ``` ##### 為什麼不合併成一個Instruction 因為1個clock的時間需大於執行時間最長的instruction的時間,若合併成一個instruction,恐加長clock時間。 --- ### J-Type |6 bit|26bit| |---|---| |opcode | address | Unconditional jump ```bash j label #goto line with label ``` ---- ## ToDo: 學組合語言 學數位邏輯?