CS 3723
 Programming Languages 
   MIPS Initial Examples:  
Operators


Basic Double Operators in MIPS: + - * /
In addition to simple double operators, the example below also shows one function, as well as the storage layout we will use.

MIPS MIPS with function Common Output
### Test of double instructions
main:   addu    $s7, $ra, $zero
        la      $s1, M # data addr

### calculate and print 8+5 ######
        l.d     $f2, 64($s1) # 8.0
        l.d     $f4, 40($s1) # 5.0
        add.d   $f6, $f2, $f4
        s.d     $f6, 80($s1)
# Print 8+5
        li      $v0, 3
        l.d     $f12, 80($s1)
        syscall
# Print NewL as ASCII char
        li      $v0, 4
        la      $a0, NewL
        syscall

### calculate and print 7-3 ######
        l.d     $f2, 56($s1) # 7.0
        l.d     $f4, 24($s1) # 3.0
        sub.d   $f6, $f2, $f4
        s.d     $f6, 80($s1)
# Print 7-3
        li      $v0, 3
        l.d     $f12, 80($s1)
        syscall
# Print NewL as ASCII char
        li      $v0, 4
        la      $a0, NewL
        syscall

### calculate and print 9*7 ######
        l.d     $f2, 72($s1) # 8.0
        l.d     $f4, 56($s1) # 5.0
        mul.d   $f6, $f2, $f4
        s.d     $f6, 80($s1)
# Print 9*7
        li      $v0, 3
        l.d     $f12, 80($s1)
        syscall
# Print NewL as ASCII char
        li      $v0, 4
        la      $a0, NewL
        syscall

### calculate and print 1/7 ######
        l.d     $f2, 8($s1)  # 1.0
        l.d     $f4, 56($s1) # 7.0
        div.d   $f6, $f2, $f4
        s.d     $f6, 80($s1)
# Print 1/7
        li      $v0, 3
        l.d     $f12, 80($s1)
        syscall
# Print NewL as ASCII char
        li      $v0, 4
        la      $a0, NewL
        syscall

# Stuff at end ###################
        addu    $ra, $s7, $zero
        jr      $ra  # ret to sys












### data declarations ############
        .data
        .align  3
M:      .double 0.,1.,2.,3.,4.,5.
        .double 6.,7.,8.,9. # cons
        .space  208  # a to z
        .space  1000 # 125 temps
Blank:  .asciiz " "
NewL:   .asciiz "\n"
Tab:    .asciiz "\t"
### Test of double instructions
main:   addu    $s7, $ra, $zero
        la      $s1, M # data addr

### calculate and print 8+5 ######
        l.d     $f2, 64($s1) # 8.0
        l.d     $f4, 40($s1) # 5.0
        add.d   $f20, $f2, $f4
        s.d     $f6, 80($s1)
        jal printit








### calculate and print 7-3 ######
        l.d     $f2, 56($s1) # 7.0
        l.d     $f4, 24($s1) # 3.0
        sub.d   $f6, $f2, $f4
        s.d     $f6, 80($s1)
        jal printit








### calculate and print 9*7 ######
        l.d     $f2, 72($s1) # 9.0
        l.d     $f4, 56($s1) # 7.0
        mul.d   $f6, $f2, $f4
        s.d     $f6, 80($s1)
        jal printit








### calculate and print 1/7 ######
        l.d     $f2, 8($s1)  # 1.0
        l.d     $f4, 56($s1) # 7.0
        div.d   $f6, $f2, $f4
        s.d     $f6, 80($s1)
        jal printit








# Stuff at end ###################
        addu    $ra, $s7, $zero
        jr      $ra  # ret to sys

### print function, prints 80($s1)
printit:
        li      $v0, 3
        l.d     $f12, 80($s1)
        syscall
# Print NewL as ASCII char
        li      $v0, 4
        la      $a0, NewL
        syscall
        jr      $ra  # ret to sys

### data declarations ############
        .data
        .align  3
M:      .double 0.,1.,2.,3.,4.,5.
        .double 6.,7.,8.,9. # cons
        .space  208  # a to z
        .space  1000 # 125 temps
Blank:  .asciiz " "
NewL:   .asciiz "\n"
Tab:    .asciiz "\t"
% spim example.s
SPIM V 7.4 of Jan 1, 2009
Copyright 1990-2004 by  ...
All Rights Reserved
See the file README for ...
Loaded:
/usr/lib/spim/exceptions.s
13  = 8+5
4  = 7-3
63  = 9*7
0.142857142857142849 = 1/7


Details of Features illustrated:
  • All operators here are applied to doubles: Students would usually see 32-bit integer operators, and not see the 64-bit double operators at all, but these last are all that we will use. Each double operator has an extra .d tacked onto the integer operator.

  • Load-load-operate-store: We will be using the most common case:
      Load into first register from memory
      Load into second register from memory
      Apply operator to the two registers, putting result in a third register
      Store from the third register into memory

    Each of first, second, and third registers could be distinct, or any two could be the same, or all three could be the same. The memory locations also don't have to be distinct.
    [Say what each of the two instructions below would do to the contents of register $f6:

      add.d   $f6, $f6, $f6
      mul.d   $f6, $f6, $f6

    What would the final value in $f6 be if it started with value 5 in it and we executed the two instructions above, one after the other?]

  • Memory use in our project: The label M will mark the start of a long sequence of locations for doubles in memory (this extremely simple organization is designed to make our compiler simpler and easier to write). Recall that each double is 64 bits or 8 bytes long.

    • First 10 locations holding the doubles 0.0 through 9.0. These are the only locations initialized ahead of time.

    • Then come 26 locations corresponding to identifiers a through z. These use 8*26=208 bytes.

    • Finally, as given in the actual programs above, there are 125 temporary locations for doubles. These use 8*125=1000 bytes. Depending on available memory, we could have a much larger number of temporaries here.

  • Memory locations are given as an offset in bytes from the initial address: The the constant 0.0 starts at offset 0 from the start of M, and 1.0 starts at offset 8 from the start of M, and so forth. [These offsets are spelled out in complete detail in the page MIPS.]

    The starting address of M is placed into the register $s1 with the "load address" pseudo-instruction

      la   $s1, M 

    In an load double or store double, the expression 24($s1) refers to the location which starts 24 bytes past the address in $s1, which for us will be 24 bytes past the start of M. This is the location of the constant 3.0.

  • Load Double and Store Double Instructions: The program above shows how these work. In most instructions, the destination is given first. This is true for a load instruction, but for a store, the destination (a location in memory) is given second.

  • Example of a Function: The program gives an example of a function, named "printit", which uses the label printit:. A function is called with a special jal ("jump and link register") instruction. This instruction puts the address of the next instruction into register $ra, and then jumps to the given label. One returns from the function in the same way one returns from main: with the instruction jr  $ra.

    Since this program uses a function, it was necessary to save the register $ra at the beginning and restore it at the end. Otherwise the jal instruction that calls printit would overwrite the return address to the system. At the end of the program, instead of returning to the system, the program would branch to the instruction just after the last use of jal. In the case here it would end up looping on one instruction indefinitely.

(Revision date: 2014-10-09. Please use ISO 8601, the International Standard.)