A high-level language program, such as
C program, is
      first compiled to an assembly code by
Compiler, and then
      transformed to object machine code by
Assembler. By combining
      multiple modules with library routines,
an executable machine
      code will be generated.
Now we are ready to introduce one particular assembly language
called MIPS instructions. The MIPS instructions will be introduced
by examples.
Example 1: 
f = (g + h) - (i + j)
the variables g, h, i, j, and f can be assigned to the registers:
g --> $11,  h --> $12,  i --> $13, 
j --> $14,  f --> $15
add    $7,   
$11,    $12       # 
$7 = $11 + $12, a temp register holds sum of (g+h)
add    $8,   
$13,    $14       # 
$8 = $13 + $14, a temp register holds sum of (i+j)
sub    $15,  $7,     
$8         #  $15 = $7 - $8,
which is the subtraction of (g+h) - (i+j)
From Example 1, we can find the difference between the high level language
and instructions are:
    (a)  High level language:   
operate on the variables
           
Instructions:                 
operate on the registers
    Instructions operate on the limited number of registers.
In our
    design, there are 32 registers in the Register File.
In contrast,
     high level language can work on large number
of variables.
   (b) There could be many variables in one expression in
   high level language, but there are only three operands
in
   MIPS add and sub
instructions.
 
 
As shown in Example 1, the number of variables could be large,
and much more than the size of registers, how does computer represent
and access such large number of variables?
Two data transfer instructions are needed to access data between
the memory and registers. Memory is just a large one-dimensional
array. Load word instruction lw moves
data from memory to
processor, and store word instruction sw
stores the data back from
processor to memory.
     -------------                                  
------------
     |                                  
|                                 
|------------|
     |                                  
|               
lw             
|------------|
     |                                  
|     <--------    |------------|
     |                                  
|                                 
|------------|
     |                                  
|      -------->   |------------|
     |                                  
|             
sw             
|------------|
     |                                  
|                      
16       |------------|
     |                                  
|                      
12       |------------|
     |                                  
|                      
8         |------------|
     |                                  
|                      
4         |------------|
     -------------                       
0          ------------
                                                          
byte address     data
           
processor                                                  
memory
                
|                                                                       
|
                
|________________________________|
 
 
Example 2: g = h + A[8];
assign variables g and h, and the starting address
of A to registers:
g --> $11,  h --> $12,  the starting
address of A--> $13
lw      $7,      
32($13)             
#  address = 32 (offset) + $13 (base), $7 = A[8]
add    $11,   
$12,    $7            
#  $11 = h + A[8]
In load word instruction lw     
$7,    32($13) , constant (here
is 32) is called offset, and the register (here it is $13) is called
base register.
The address of memory is calculated by (offset + base). The register
$7 is called destination register in lw
.  lw gets data from the memory
from the specified address and writes data to the destination register.
Since the 8-bit byte address, one 32-bit word would take
4 bytes. Suppose A[0] is in address 1000, A[1] will be in
address 1004, and A[2] will be in 1008, and A[8] will
be in 100 + 8*4 = 100 + 32. That is why we use 32 as the
offset for A[8] in lw instruction.
Example 3: A[12] = h + A[8];
In Example 2, we used lw instruction to
get data from memory
to register. This example will use sw
instruction to write data
from register back to memory.
assign the variable h and the starting address A to registers:
h --> $12,  the starting address of A-->
$13
lw      $7,   
32($13)        #  $7 = A[8],
add    $8,   
$12,    $7      #  $8 = h
+ A[8]
sw      $8,   
48($13)        #   A[12] =
$8
The format of sw instruction is similar
to that of lw.
The constant (here 48) is the offset, and the register
(here is $13) is called the base. The difference is the
register (here $8)  is called source
register in sw rather than
destination register in lw .
 
 
1. Instruction format of add and sub
    All MIPS instructions are represented by 32-bits
in the
     binary representation. The 32 bits are divided
into 6
     fields.
      ---------------------------------------
      |      
op       |     
rs      |      rt      
|       rd     |  
shamt   |   funct      |
      ---------------------------------------
           
6-bits   5-bits      5 bits     
5 bits      5 bits     6 bits
 
    op : 6 bits, opcode,
basic operation.
    rs :  5 bits,
the first register operand
    rt :  5 bits,
the second register operand
    rd :  5bits, the 
destination register operand
    shamt : 5 bits, shift
amount. This 6-bit field is only used for the
                 
shift instruction.
    funct : 6 bits, function
code.
Example 4: add $8, $17, $18
decimal representation:
       ---------------------------------------
      |       
0         |     
17     |      18    
|      8      |       
0      |         
32        |
      ---------------------------------------
binary representation:
       ---------------------------------------
      |  000000  |  10001 
|  10010   |   01000  |  00000  
|    100000    |
      ---------------------------------------
Example 5: sub $8, $17, $18
decimal representation:
       ---------------------------------------
      |       
0         |     
17     |      18    
|      8      |       
0      |         
34       |
      ---------------------------------------
binary representation:
       ---------------------------------------
      |  000000  |  10001 
|  10010   |   01000  |  00000  
|    100100    |
      ---------------------------------------
2. Instruction format of lw and sw
    All MIPS instructions are represented by 32-bits
in the
     binary representation. The 32 bits are divided
into 6
     fields.
      ---------------------------------------
      |      
op       |     
rs      |      rt      
|                     
address                 
|
      ---------------------------------------
           
6-bits   5-bits      5 bits                            
16 bits
 
    op : 6 bits, opcode,
basic operation.
    rs :  5 bits,
base register operand
    rt :  5 bits,
the destination register for lw instruction,
           
and source register for sw
 
Example 6: lw $17, 100($18)
       ---------------------------------------
      |      
35       |     
18      |      17      
|               
100                            
|
      ---------------------------------------
Example 7: sw $17, 100($18)
       ---------------------------------------
      |      
43        |     
18      |      17      
|               
100                            
|
      ---------------------------------------
 
Example          if
(i == j) goto L1
                             
f = g + h;
                 
L1:      f = f - i;
assign variables to registers:
i--> $13,  j --> $14,  g --> $15, 
h --> $16,   f --> $17
 
         beq    
$13,  $14, L1   # if $13 == $14, goto branch L1, else go
to next instruction
         add    
$17, $15, $16
L1:   sub    
$17, $17, $13