# 計組第一章 指令:計算機語言
[toc]
## big endian & little endian
big endian 最左邊的字元(最大)放入最低記憶體位置
## reg table
|name|number|usage|
|-|-|-|
|$at|$1|preserved for assembler|
|$ v0-$v1|$2-$3|values for result回傳結果|
|$ a0-$a3|$4-$7|arguments用於副程式呼叫傳遞引述用的|
|$ra|$31|return address|
|$gp|$28|global pointer|
|$sp|$29|stack pointer|
|$fp|$30|frame pointer|
|$ s0-$s7|$16-$23|saved|
|$ t0-$t7|$8-$15|temporaries|
|$ t8-$t9|$24-$25|more temporaries|
|$ zero|$0|the constant value 0|
## 記憶體管理
* stack:放置區域變數,方向由上往下
* heap:放置動態指標變數,方向由下往上
* static data:放置可供其他程序使用之變態變數,這個區域在程式執行過程中大小不會鍵盤
* code(Text):放置程式碼的區域

## jave compiler

## 算術指令(R-type)
## 資料轉移指令(lw,sw)
## 流程控制指令(beq)
## 邏輯運算
## 重點十一:常數
addi $29,$29,4
<font color="red">邏輯運算類的,常數左邊用16個0擴充,若為算術類的,則常數左邊用sign來擴充
andi => 0補充
addi => 看sign補充1或0
</font>
## 32位元立即運算元
載入立即上半部(lui)能將16位元的常數載入到暫存器的左半邊16位元而將右半邊清為0
ex:lui $t0,1010101010101010
=>1010101010101010 0000000000000000
## 重點十二:組合語言與機器語言
R-type
|op|rs|rt|rd|shamt|funct|
|-|-|-|-|-|-|
|6|5|5|5|5|6|
I-type
|op|rs|rt|address/immediate|
|-|-|-|-|
|6|5|5|16|
J-type
|op|26-bit address|
|-|-|
|6|26|
* add $t0, $s1, $s2
|op|rs|rt|rd|shamt|funct|
|-|-|-|-|-|-|
|0|17|18|8|0|32|
* lw $ t0,32($s2)
|op|rs|rt|address/immediate|
|-|-|-|-|
|35|18($s2)|8($t0)|32|
### jump與beq
* beq可以跳距離目前指令位址跳-2^15^~2^15^-1字組
* jump一整個256Mb block都可以跳到
* jump中4bit不用紀錄因為記憶體空間切成16個大小相同之256Mbytes區塊,任何一個程式只能侷限於一個區塊內,而記憶體中必須對齊4的整數倍數記憶體位址,故最右邊2bit不用紀錄
=> 26 = 32 - 4 - 2
## 重點十三:程序呼叫
1.將引數放在程序可以存取的地方(a0-a3)
2.將控制權轉移給程序(jal)
3.取得程序所需的儲存資源(s0-s7)
4.執行所指定的工作
5.將所得結果放在呼叫程式可以存取得到的地方(save v0-v1)
6.將控制權交回給呼叫程序(jr $ra)
* mips的堆疊是<font color=red>由高向低</font>位址成長,<font color=red>因此借空間必須用減的sp=sp-4</font>
```c
int leaf_example(int g,h,i,j)
{
int f;
f = (g+h) - (i+j);
return f;
}
leaf_example:
addi $sp,$sp,-4
sw $s0,0($sp)
---------------
add $t0,$a0,$a1
add $t1,$a2,$a3
sub $s0,$t0,$t1
---------------
add $v0,$s0,$zero
lw $s0,0($sp)
addi $sp,$sp,4
jr $ra
```
```c
int fact(int n)
{
if(n < 1) return 1;
else return (n*fact(n-1));
}
fact:
addi $sp,$sp,-8
sw $ra,4($sp)
sw $a0,0($sp)
slti $t0,$a0,1
beq $t0,$zero,L1
---------------
addi $v0,$zero,1
addi $sp,$sp,8
jr $ra
L1:
addi $a0,$a0,-1
jal fact
---------------
lw $a0,0($sp)
lw $ra,4($sp)
addi $sp,$sp,8
mul $v0,$a0,$v0
jr $ra
```
## 重點十四:不講
## 重點十五:MIPS定址模式
* 立即定址模式(immediate addressing):運算元即為包含在指令本身的16位元常數
addi,andi,ori
* 暫存器定址模式(register addressing):運算元在暫存器中
add,sub,adn,or
* 基底或位移定址模式(base or displacement addressing):運算元在記憶體中,而齊記憶體位址計算為基底暫存器的內容加上16位元的常數而得
lw,sw
* 程式計數器相對定址模式(PC-relative addressing):目的位址為程式計數器的內容加上指令中的常數
beq,bne
* 虛擬直接定址模式(pseudodirect addressing):跳躍目的位址為指令的26位元與程式計數器高位元的結合
j,jal
## 重點十六:指令集設計原則
* 一致才會簡單(simplicity favors regularity)
讓所有指令保持單一大小
一律要求三個運算元
讓不同指令格式的暫存器欄位在同樣的位置
* 越小就越快(smaller is faster)
32個register,暫存器越少功率消耗也越低
* 使經常發生的事件快速(make the common case fast)
使用PC-相對定址法語分支跳躍及使用立即定址法以得到常數運算元
* 好的設計會有好的折衷方案(good design demands good)
## 重點十六:指令集設計原則
|RISC|CISC|
|-|-|
|所有指令都有相同長度|長短不一|
|少數幾種定址模式|多種|
|少數幾種指令格式|多種指令格式|
|算數指令的運算元址允許來自暫存器|可來自記憶體|
|記憶體中的資料須先載入至暫存器後才能處理|記憶體中的資料可以直接處理而不須事先載入暫存器|
###### tags: `architecture` `chp1`