Computer Systems


MIPS - Microprocessor without Interlocked Pipeline Stages

Underlying design principles:

  • Simplicity favours regularity

  • Make the common case fast

  • Smaller is faster

  • Good design demands good compromises

32 Bit RISC Processor

  • Around 80 instructions in the instruction set

  • 32 general purpose registers $r0 - $r31

  • $r0 is special and always contains the value 0

  • The MIPS processor has a super pipelined architecture - each instruction is broken down into a sequence of ‘micro’ instructions

Design principles

MIPS is a reduced instruction set computer (RISC), with a few simple instructions. Other architectures, such as intel’s x86 are complex instruction set computers (CISC)

  • Simplicity favours regularity

    • Consistent instruction format: same number of operands (two sources and one destination) is easier to encode and handle in hardware
  • Make the common use case fast

    • MIPS includes only simple, commonly used instructions

    • Hardware to decode and execute instructions can be simple, small and fast

    • More complex instructions (that are less common) performed using multiple simple instructions

  • Smaller is faster

    • MIPS includes only a few registers

      NameRegister NoUsage
      $00The constant 0
      $at1Assembler temporary
      $v0 - $v12-3Function return values
      $a0 - $a34-7Function arguments
      $t0 - $t78-15Temporaries
      $s0 = $s716-23Saved variables
      $t8-$t924-25More temporaries
      $k0-$k926-27OS Temporaries
      $gp28Global Pointer
      $sp29Stack pointer
      $fp30Frame pointer
      $ra31Function return address
  • Good design demands good compromises

    • Multiple instruction formats allow flexibility, for example some use 3 operands, some 2

    • Number of instruction formats kept small to adhere to design principles 1 and 3

    • Other formats appear in assembler, but are transformed into machine code to fit with this format

Instruction Types

R Type

R Type

3 Register Operands:

  • rs,rt: source registers
  • rd: destination register

Other fields:

  • op: the operation code or opcode (0 for R-type instructions)
  • funct: the function, with opcode, tells the computer what operation to perform
  • shamt: the shift amount for shift instructions, otherwise 0

R Type example


s11 $s0, $s1, 5

“shift bits in register 15 5 places and put it in register 15”

Field values:


I Type

I type

3 Operands:

  • rs,rt: register operands
  • imm: 16 bit two’s complement immediate

Other fields:

  • op: the operation code or opcode (0 for R-type instructions)


addi, $s0, $s1, 5

“Add value in register 17 and ‘5’ and put the answer in register 16”

Field values:


J Type

J type

  • 26-bit address operand: addr
  • Used for jump instructions, j
  • Rarely used in assembly
  • Typically use the R type instruction jr name or jr $s0


How do we address the operands

Register Only

add $s0, $s1, $s2


(16 bit two’s complement integer)

addi $s0, $s1, 5
ori $t3, $t7, 0xFF

Base addressing

Address of operand is given by base address + signed immediate

lw $s0 0($sp)
sw $s0, -12($t0)

PC relative

Jump so far from the current position

beq $t0, $0, 3

There is the 3 at the end of the pc relative jump because it jumps 3 lines ahead in the program

Obtaining memory addresses - declare data at the beginning of the program and look up addresses of variables

string1: .space 10
string2: .asciiz "Oh:"
var1: .word 1234

.globl main
lw $s0, var1
la $a0, string1

Loading 32 Bit words

How, if you only have 16 bit immediates?

  • Load the first 16 bits with a special command, then add the rest
  • E.g. want to add 0xFEDC8765
  • First add 0xFEDC0000 then add 0x00008765
lui $s0, 0xFEDC
ori $s0, $s0, 0x8765

This loads half into the left half of the bits, and the other half into the right half

OS Calls

Set call type in register $v0 e.g. ori $v0, $0, 10

print_int1$a0 = integer to be printed
print_float2$f12 = float to be printed
print_double3$f12 = double to be printed
print_string4$a0 = address of string in memory
read_int5integer returned in $v0
read_float6float returned in $v0
read_double7double returned in $v0
read_string8$a0 = memory address of string input buffer $a1 = length f string buffer

Multiplication and Division

32 x 32 multiplication, 64 bit result:

  • mult $s0, $s1
  • Result in special registers lo, hi

32-bit division, 32 bit quotient, remainder

  • div $s0, $s1
  • Quotient in lo
  • Remainder in hi

Moves from lo/hi special registers

  • mflo $s2
  • mfhi $s3

MIPS Function Calls

MIPS Function Calls



  • Passes arguments to callee, using registers $a0-$a4
  • Jumps to calee - using jal


  • Performs the function
  • Returns result to caller - using registers $v0-$v1
  • Returns to point of call - using jr to $ra
  • Must not overwrite registers or memory needed by caller

The stack:

  • A dynamically sized chunk of memory
  • $sp always contains the address of the head of the stack

To add to the stack

  • Move the stack down one pos
  • Write the value
addi $sp, $sp, -4
sw $s0, 0($sp)

To pop from the stack

  • Read the value
  • Move the stack pointer up one pos
addi $sp, $sp, 4
lw $s0, 0($sp)

Recursive call:

  • Must preserve $ra so that prior call can return to the correct place
  • So store it on stack before calling a function
  • Reinstate it afterwards


  • Put arguments in $a0-$a3
  • Save any needed registers
  • jal callee
  • Restore registers
  • Look for result in $v0


  • Save registers that might be disturbed
  • Perform function
  • Put result in $v0
  • Restore registers
  • jr $ra

Example - Factorials

Factorials example