Day 11
I. Last Time:
Hw #3 Posted!!
Test #1 Grades posted later today / Tomorrow

II. New Stuff:   
A. MIPS Machine:
Diagram CPU:
Control
Datapath: ALU / Registers / Memory

       Instructions in MIPS do 1 of 3 things:
Data Movement:
Move data around:
Register<->Memory
Register<->Register
Data Manipulation:
Actually Change/calculate data
ALWAYS register(s)->Register
Ex: ADD
Control:
Decision Making:
"if" statements
"whiles"
These are called "Branching"
because the "path" of instructions
that the program takes changes or branches
off.

       Highlights:
           32, 32-bit GENERAL PURPOSE registers
           (General Purpose - Few registers have special 
               meaning to the hardware. They DO have special 
               meaning to the programmer though!)

           Data Manipulation can ONLY be performed on the 
           32 values available in registers - If you need to 
           work with larger amounts of info. you must "shuttle"
           data to/from memory via the data movement commands.
           (This is typical of RISC Machines)

           Co-Pro - In MIPS a seperate Co-Processor deals with 
           some types of arithmatic. (Float Point) and interupts.

     The Challenge: Write a program to do something usefull given 
        these constraints/rules. It's a challenging puzzle and will
        give us some insight into:
            A. How the CPU works
            B. How to write better programs even in higher level
               languages
            C. Insight into the design/constraints of some higher 
               level languages.                


       B. Register Names: Registers have both a symbolic and a numeric Name
           Numeric name: $<number>
            $0  - $zero - Register[0]
            $1  - $at   - Register[1]
            $2  - $v0   - Register[2]
            //    v1,a0-a3,
            $8  - $t0   - Register[8] "T emporaries"
            $9  - $t1   - Register[9]
            ...
            $15 - $t7   - Register[15]
            $16 - $s0   - Register[16] "S tatic"
            $17 - $s1   - Register[17]
            ...
            $23 - $s7   - Register[23]
            $24 - $t8   - Register[24]
            $25 - $t9   - Register[25]
          We'll only work with the "s-registers" today

          Names established to enforce usage conventions so 
          different assembly programmers can work together.
          We'll discuss these usage conventions next week.
          They are established to ensure that modules written
          by different programmers will successfully work 
          together. They are NOT enforced by the hardware but 
          they WILL be enforced by me.
            
     C. Commands: Data Manipulation - Simple Math
        Basic Format:
           add dest_reg, srca, srcb    # dest_reg=srca+srcb
        I want to add what's in register $s4 to what's in $s5 
        and store the result in $s3:
           add $s3,$s4,$s5
        (Addition is commutative so we could also go with:
           add $s3,$s5,$s4)
        Also, we could use the register NUMBERs rather than names:
            add $19,$20,$21

D. R-Format Instructions
       R-format instructions - 
              Working between registers only - all data comes 
              from a register              
     
        R-Format:
          6 bits  5 bits 5 bits 5 bits 5 bits 6 bits
          op code   rs     rt     rd    shamt func
          The op-code and function code together determine 
          the instruction. rs, rt and rd specify the registers 
          to use. Ignore shamt for the moment (assume 0)
          add inst: R-Format, op=0, func=32d = 10 0000b
          add $s1, $s2, $s4
          RD = $s1, RS=$s2, RT=$s4
          NOTE: NOT in the order of the written instruction!!!!
          s1 = $17 = 1 0001b
          s2 = $18 = 1 0010b
          s4 = $20 = 1 0100b
          NOTE: 5-bits allows you to pick a number from 0-31. 
                I.e. to pick one of the 32 registers.
          op = 00 0000b
          rs = 1 0010 b
          rt = 1 0100 b
          rd = 1 0001 b
          shamt = 0 0000b
          funct = 10 0000b
          00 0000 | 1 0010 | 1 0100 | 1 0001 | 0 0000 | 10 0000
          0000 0010 0101 0100 1000 1000 0010 0000
          =0x02548820
          So, now when I give you a word in binary it can be interpreted
          at least 5 ways: ASCII text, and Instructions, a signed number, 
          an unsigned number, and a floating point number.
          Note that this is JUST a "number" in binary - This is
          what Von Neumann had in mind for the stored program concept.

          These instruction formats allow the "control" to read back
          and "decode" the instruction to control the ALU and datapath. 
          We'll discuss this in the coming chapters.

E. Subtraction
Basic Format:
           sub dest_reg, srca, src_regb    # dest_reg=srca-srcb

        I want to subtract register $s5 from register $s2 and store the
        result in register $s4:
           sub $s4,$s2,$s5 # s4=s2-s5

    F. More complex equations:
           WE must perform operations in the proper order and 
           store temporary results - these are things that usually
           the compiler does for us and we take for granted...
           f = (g + h) - (i + j)
           Assume that f in in register s0
                       g is in register s1
                       h                s2
                       i                s3
                       j                s4

           What do we do?
                Break into smaller operations - just as if we were
                solving it by hand: 
                     x=g+h
                     y=i+j
                     f=x-y
                Pick a place for x and y. Be carefule not to trounce
                another register already being used: 
                    $s5 and $s6 respectively
           add $s5,$s1,$s2 # x=g+h
           add $s6,$s3,$s4 # y=i+j
           sub $s0,$s5,$s6 # f=x-y = (g+h)-(i+j)

    G. Retreiving from Memory: lw
      lw - load a WORD (32-bits for MIPS) out of memory
      Syntax/Format: lw dest, offset(index)
      Meaning: Read the Word that begins at Memory[offset+reg[index]]
               and put into the dest register.
               Offset is a number (specifically a 16-bit signed number)
      Example: lw $s0, 4($s1)
               Means get the word that's 4 bytes past the address(index)
               contained in $s1
      Ex: Using a Big Endian Machine!!!
          Mem[0] = 0x00
          Mem[1] = 0x00
          Mem[2] = 0x02
          Mem[3] = 0x01
          Mem[4] = 0x00
          Mem[5] = 0x00
          Mem[6] = 0x02
          Mem[7] = 0x04
          Mem[8] = 0x00
          Mem[9] = 0x00
          Mem[10] = 0x01
          Mem[11] = 0x01
      Q. If register s1 contains 0:
         What's the reqult of lw $s2,0($s1) -> s2=0x201
                              lw $s3,4($s1) -> s3=0x204
      Q. If register s1 contains 4:
         What's the result of lw $s2,0($s1) -> s2=0x204
                              lw $s3,4($s1) -> s2=0x101
      Q. If register s1 contains 4:
         What's the result of lw $s2,-4($s1) -> s2=0x201

      Q. What if this was a Little Endian Machine instead?

      NOTE: This just "copies" out of memory into the register
      (A data movement command)

   H. Putting data back into memory: sw
      sw - store a WORD (32-bits for MIPS) from reg into mem
      Syntax/Format: sw src, offset(index)
      Meaning: Store the Word from the register into 
               Memory[offset+reg[index]]
      Example: sw $s0, 4($s1)
               Means copy what's in register $so into the 
               word of memory begining at Mem[4+reg[s1]].
      Q. What happens when: sw $s3,0($s1)
                            sw $s3,-4($s1)

   I. Simple Math & Arrays:
      From Book: A[8]=h+A[8]. 
      h is in register s2, A's "Base Address" is in $s3
      A is an array of WORDS
      1. Retrieve A[8]:
         lw $s4,32($s3)   # s4 = A[8]. (8th word = 4*8 bytes = 32)
      2. Add:
         add $s4,$s4,$s2  # s4=h+A[8]
      3. Store: 
         sw $s4,32($s3)   # A[8]=h+A[8]

      g=h+A[i]
      A's "base" (Address) is in $s3
      g,h,i in $s1,$s2, and $s4
      1. Compute Address:
         add $s1,$s4,$s4 # s1=i+i=2*i
         add $s1,$s1,$s1 # s1=s1+s1=2*s1=2*2*i = 4i
         add $s1,$s1,$s3 # s1=s1+Base of A = A+4i
      2. Load A[i]
         lw $s1,0($s1)   # Load A[i] 
      3. Add h to A[i]:
         add $s1,$s2,$s1 # g=h+A[i]                     

   J. I-Format Instructions - 
         Immeadiate data - Some Data is included in 
         the instructions. Data Manipulation and some 
         control instructions

      I-Format Instructions: Immediate data is encoded within the 
      instruction itself.

      Ex: Lw & Sw, The OFFSET is a part of the instruction!!!
          (I.e. immeadiately available)
      Format: 
          6 bits  5 bits 5 bits      16 bits
          op code   rs     rt    Immediate data         
      Ex:
         lw $s4,32($s3)   # s4 = A[8]. (8th word = 4*8 bytes = 32)
       lw op = 35d = 10 0011b
       rs = $s3 = $19 = 1 0011b
       rt = $s4 = $20 = 1 0100b
       offset = 32 = 10 0000b = 0000 0000 0010 0000b (16-bit)
       10 0011 | 1 0011 | 1 0100 | 0000 0000 0010 0000b
       1000 1110 0111 0100 0000 0000 0010 0000b
       0x8E740020
           
       NOTE: The immediate data is limited to 16 bits. 
             So, the largest value is 64k unsigned, -32k-32K signed.
       NOTE: We can also "reverse" the process. 

   K. Misc. Working with Bytes: lb & sb can be used to 
      load and store bytes in the same way that lw & sw 
      can be used to store words. 
      Differences: No Word Alignment Constraints
                   Loads byte into LOWER byte of reg, rest is 0
                   Stores byte from LOWER byte of reg

 III. Next Time:
A. Return Test I
C. Memory & Arrays!