Introduction to MIPS Processor The processor we will be considering in this tutorial is the MIPS processor. The MIPS processor, designed in 1984 by researchers at Stanford University, is a RISC (Reduced Instruction Set Computer) processor. Compared with their CISC (Complex Instruction Set Computer) counterparts (such as the Intel Pentium processors), RISC processors typically support fewer and much simpler instructions. RISC processor can be made much faster than a CISC processor because of its simpler design. These days, it is generally accepted that RISC processors are more efficient than CISC processors; and even the only popular CISC processor that is still around (Intel Pentium) internally translates the CISC instructions into RISC instructions before they are executed. MARS is MIPS assembler and simulator. It runs on Windows, OSX, and Linux; just make sure that you have the Java J2SE 1.5 (or later) SDK installed on your computer. Some MIPS instructions don t have direct hardware implementations. MIPS assembler recognizes them and translate them to sequence of MIPS True instructions MIPS Pseudo Instruction: A MIPS instruction that does not turn directly into a machine language instruction, but into other MIPS instructions Register Move move reg2,reg1 Expands to: add reg2,$zero,reg1 The MIPS family provides instructions to perform the following operations: Load registers with values, either from RAM or with literal values. Store register values (i.e. copy them) out to RAM locations. Basic integer arithmetic: add, subtract, multiply, divide with remainder. Basic floating-point arithmetic: add, subtract, multiply, divide. Logical operations: AND, OR, NOT, exclusive OR (XOR). Shift operations: shift left, shift right. Comparison operations: ==,!=, <, >, <=, >= Instructions to change the flow of control: relative branches and jumps. The basic structure of a MIPS assembly language program is: Data section, where your variables and their data sizes are named. The assembler will choose where in RAM to store your variables. The data section is identified by a line with the assembler directive.data Code section, which contains your assembly language instructions. The code section is identified by a line with the assembler directive 1
.text Your code section must contain a starting point for your program's execution, marked by the label main: and your main code must end with a call to the exit system call, which tells the CPU to stop the program. 2
3
4
Instruction Set 5
Supported Syscalls by MARS System calls are asking OS to perform services syscall: o checks $v0 for the type of the service o the arguments (if any) are passed in $a0 - $a3 6
MIPS Assembly Language Overview Data representation We cannot refer to individual bits Addressable groups in MIPS: o byte - 8 bits o word - 4 bytes = 32 bits o halfword - 2 bytes = 16 bits Two's complement representation To represent a negative number: 1. start with the positive binary representation 2. invert every bit 3. add 1 to the result Examples with 4-bit integers: -1 == 0001 ==> 1110 ==> 1111-4 == 0100 ==> 1011 ==> 1100-7 == 0111 ==> 1000 ==> 1001 9. Sign extension To change the size of an integer without changing its value o if positive (left-most bit 0), pad left with 0s o if negative (left-most bit 1), pad left with 1s 12. Assembly program template Data and code segments # comment.data # constant and variable definitions go here.text # assembly instructions go here 7
16. MIPS register names and conventions Number Name Usage Preserved? ------ ------- ----------------------- ---------- $0 $zero constant 0x00000000 N/A $1 $at assembler temporary No $2-$3 $v0-$v1 function return values No $4-$7 $a0-$a3 function arguments No $8-$15 $t0-$t7 temporaries No $16-$23 $s0-$s7 saved temporaries Yes $24-$25 $t8-$t9 more temporaries No $26-$27 $k0-$k1 reserved for OS kernel N/A $28 $gp global pointer Yes $29 $sp stack pointer Yes $30 $fp frame pointer Yes $31 $ra return address Yes Assembly program example.eqv SYSCALL_PRINT_STRING 4.eqv SYSCALL_EXIT_PROG 10.data # data segment begins # Define a greeting message: Message:.asciiz "Hello World!\n".text # Print the greeting message: li $v0, SYSCALL_PRINT_STRING la $a0, Message syscall # print string # Return to the operating system: li $v0, SYSCALL_EXIT_PROG syscall # exit program Integer Multiplication Result of multiplication is a 64-bit number, stored in two 32-bit registers named "hi" and "lo" # Instruction # Meaning in pseudocode mult $t1, $t2 # hi,lo = $t1 * $t2 mflo $t0 # $t0 = lo mfhi $t3 # $t3 = hi 8
There is a shortcut (macro instruction): mul $t0, $t1, $t2 # hi,lo = $t1 * $t2; $t0 = lo which expands to: mult $t1, $t2 mflo $t0 Integer Division Computes quotient and remainder. Simultaneously stores quotient in "lo" and remainder in "hi" # Instruction # Meaning in pseudocode div $t1, $t2 # lo = $t1 / $t2; hi = $t1 % $t2 mflo $t0 # $t0 = lo quotient mfhi $t3 # $t3 = hi remainder Reading from data memory Basic instruction to read integer from memory is called load word lw $t1, 4($t2) # $t1 = Memory[$t2+4] Here, $t2 contains the base address, and 4 is the offset Note that there is a shortcut: lw $t1, 0($t2) lw $t1, $t2 lw $t1, label lw $t1, label + 4 # the same # $t1 = Memory[label] # $t1 = Memory[label+4] Writing to data memory Basic instruction to write integer to memory is called store word sw $t1, 4($t2) # Memory[$t2+4] = $t1 $t2 contains the base address 4 is the offset 9
Shortcuts: sw $t1, 0($t2) sw $t1, $t2 # the same sw $t1, label # Memory[label] = $t1 sw $t1, label + 4 # Memory[label+4] = $t1 Expression and Assembly example # Pseudocode: # c = (a+3) * (b-2) + a # Register mappings: # a: $t0, b: $t1, c: $t2 # tmp1: $t3, tmp2: $t4, tmp3: $t5 addi $t3, $t0, 3 # tmp1 = a+3 subi $t4, $t1, 2 # tmp2 = b-2 mul $t5, $t3, $t4 # tmp3 = tmp1 * tmp2 add $t2, $t5, $t0 # c = tmp3 + a Example adding three numbers.data # Add three numbers in memory and print the result # string to print before the result STR_PROMPT:.asciiz "Result: " # numbers to add nums:.word -77, 13, -5 # numbers to add result:.word 0 # result.text # print the initial string li $v0, 4 # ask for print string service la $a0, STR_PROMPT syscall # load three numbers into registers la $t0, nums lw $t1, 0($t0) # lw $t1, nums lw $t2, 4($t0) # lw $t2, nums + 4 lw $t3, 8($t0) # lw $t3, nums + 8 # add and store the result in $a0 for printing add $a0, $t1, $t2 # add the first two numbers add $a0, $a0, $t3 # add the third to the sum # save a0 in memory sw $a0, result # print the result li $v0, 1 # ask for $a0 print service 10
syscall # exit li $v0, 10 # ask for exit service syscall Bitwise logic operations and $t1, $t2, $t3 or $t1, $t2, $t3 xor $t1, $t2, $t3 # $t1 = $t2 & $t3 (bitwise and) # $t1 = $t2 $t3 (bitwise or) # $t1 = $t2 ^ $t3 (bitwise xor) Immediate formats andi $t1, $t2, 0x0F # $t1 = $t2 & 0x0F (bitwise and) ori $t1, $t2, 0xF0 # $t1 = $t2 0xF0 (bitwise or) xori $t1, $t2, 0xFF # $t1 = $t2 ^ 0xFF (bitwise xor) Bitwise examples 1 0 1 0 and 0 0 1 1 ------- 0 0 1 0 1 0 1 0 or 0 0 1 1 ------- 1 0 1 1 1 0 1 0 xor 0 0 1 1 ------- 1 0 0 1 Logical expressions seq $t1, $t2, $t3 # $t1 = $t2 == $t3? 1 : 0 sne $t1, $t2, $t3 # $t1 = $t2!= $t3? 1 : 0 sge $t1, $t2, $t3 # $t1 = $t2 >= $t3? 1 : 0 sgt $t1, $t2, $t3 # $t1 = $t2 > $t3? 1 : 0 sle $t1, $t2, $t3 # $t1 = $t2 <= $t3? 1 : 0 slt $t1, $t2, $t3 # $t1 = $t2 < $t3? 1 : 0 MARS Immediate formats: slti $t1, $t2, 42 # $t1 = $t2 < 42? 1 : 0 11
...and so on... Logical expression example 1 # Pseudocode: # c = ( a < b ) ( ( a + b ) == 10 ) # Register mappings: # a: t0 # b: t1 # c: t2 add $t3, $t0, $t1 # tmp = a+b li $t4, 10 # tmp = tmp == 10 seq $t3, $t3, $t4 slt $t2, $t0, $t1 # c = a < b or $t2, $t2, $t3 # c = c tmp Logical expression example 2 # Pseudocode: # c = (a < b) && ((a+b) % 3) == 2 # Register mappings: # a: t0, b: t1, c: t2 # tmp1: t3, tmp2: t4 add $t3, $t0, $t1 # tmp1 = a+b li $t4, 3 # tmp1 = tmp1 % 3 div $t3, $t4 mfhi $t3 seq $t3, $t3, 2 # tmp1 = tmp1 == 2 slt $t4, $t0, $t1 # tmp2 = a < b and $t2, $t3, $t4 # c = tmp2 & tmp1 Conditional jumps # Basic instructions beq $t1, $t2, label bne $t1, $t2, label bgez $t1, label bgtz $t1, label blez $t1, label bltz $t1, label # Macro instructions beqz $t1, label bnez $t1, label beq $t1, 123, label bne $t1, 123, label bge $t1, $t2, label bgt $t1, $t2, label # if ($t1 == $t2) goto label # if ($t1!= $t2) goto label # if ($t1 >= 0) goto label # if ($t1 > 0) goto label # if ($t1 <= 0) goto label # if ($t1 < 0) goto label # if ($t1 == 0) goto label # if ($t1!= 0) goto label # if ($t1 == 123) goto label # if ($t1!= 123) goto label # if ($t1 >= $t2) goto label # if ($t1 > $t2) goto label 12
bge $t1, 123, label bgt $t1, 123, label ble... blt... # if ($t1 >= 123) goto label # if ($t1 > 123) goto label # similar # similar Conditional jump example 1 # Pseudocode: # if (a < b + 3) # a = a + 1 # else # a = a + 2 # b = b + a # Register mappings: # a: $t0, b: $t1 addi $t2, $t1, 3 # tmp = b + 3 blt $t0, $t2, ifless # if (a < tmp) addi $t0, $t0, 2 # otherwise a = a + 2 j finish ifless: addi $t0, $t0, 1 # if true, a = a + 1 finish: add $t1, $t1, $t0 # b = b + a Conditional jump example 2 # Pseudocode: # if (a < b + 3) # a = a + 1 # b = b + a # Register mappings: # a: $t0, b: $t1 # One implementation addi $t2, $t1, 3 # tmp = b + 3 blt $t0, $t2, ifless # if (a < tmp) j finish ifless: addi $t0, $t0, 1 # if true, a = a + 1 finish: add $t1, $t1, $t0 # b = b + a # Another implementation addi $t2, $t1, 3 # tmp = b + 3 bge $t0, $t2, finish # if (a >= tmp) goto finish addi $t0, $t0, 1 # a + 1 finish: add $t1, $t1, $t0 # b = b + a 13
while loop example # Translate to lower-level pseudocode: # sum = 0 # i = 0 # while (i < n) { # sum = sum + i # i = i + 1 # } li $t2, 0 # sum = 0 li $t1, 0 # i = 0 loop: bge $t1, $t0, endloop # Loop begins: if i >= n goto endloop add $t2, $t2, $t1 # sum = sum + i addi $t1, $t1, 1 # i = i + 1 j loop endloop: Pipelining Goal: execute programs faster How: o separate processor into stages o overlap the execution of consecutive instructions MIPS is designed for pipelining Pipelining non pipelining 14
MIPS Instruction pipelining Pipeline stages: 1. IF - Instruction Fetch 2. ID - Instruction Decode 3. EX - EXecute 4. ME - MEmory access 5. WB - Write Back MIPS Instruction pipeline example Pipeline Hazards Hazard is a dependency that breaks pipelining o Data hazard program needs a value that has not been computed yet 15
o Control hazard program does not know which instruction is next Data hazard example: add $t1, $t2, $t3 # IF ID EX ME WB-$t1 is set here addi $t4, $t1, 1 # IF ID-$t1 is read here EX ME WB Solution 1: processor inserts delays add $t1, $t2, $t3 # IF ID EX ME WB-$t1 is set here addi $t4, $t1, 1 # IF XX XX XX ID-$t1 is read here EX ME WB Solution 2: processor reorders instructions to avoid data hazards Examples Take 2 numbers from user and print the sum of them 1 1 Swap numbers Print 2 different strings 16
Addition, subtract, multiplication, division Read from memory using loop 17