# 計組第一章 指令:計算機語言 [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):放置程式碼的區域 ![](https://i.imgur.com/E2T4Q0K.png) ## jave compiler ![](https://i.imgur.com/Qw1vu5i.png) ## 算術指令(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`