---
# System prepended metadata

title: 計算機組織 ISA
tags: [計算機組織]

---

# 計算機組織 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: 
學組合語言
學數位邏輯?