title: MIPS Calculator
body: <p>I'm trying to finish up this MIPS calculator, super basic, my first mips program.  It doesn't have to handle overflow or anything like that, just has to work on small, positive numbers.</p>
  
  <p>I've not checked my algorithms for multiply and divide, because I am just trying to get add working.</p>
  
  <p>I cannot for the life of me figure out why the ints will not read in and also I'm getting a memory out of bounds when I call lb $a0, op to display the operator for output and don't understand why.</p>
  
  <p>I'm new to this so anything is probably helpful.  Thanks in advance.</p>
  
  <pre><code>        .data
                          # const string for welcome
  welc:       .asciiz "Welcome to SPIM Calculator 1.0!\n" 
  p_int:      .asciiz "\nPlease give an integer: "
  p_op:       .asciiz "\nPlease give an operator: "
  i_err:      .asciiz "\nInput Incorrect, bad operator!\n"
  again_str:  .asciiz "Another calculation? (y/n)"
  rmndr:      .asciiz " r: "
  new_line:   .asciiz "\n"
  
  int1:   .word 1         # space to hold int 1
  int2:   .word 1         # space to hold int 2
  raw_in: .space 1        # space to hold raw input
  op:     .space 1        # space to hold operator char
  a_char: .space 1        # space to hold again char
  
  out:    .word 1         # space to hold output
  remain: .word 1         # space to hold remainder
  
  #operator constants
  c_plus: .ascii "+"      # const for +
  c_min:  .asciiz "-"     # const for -
  c_mult: .asciiz "*"     # const for *
  c_divi: .asciiz "/"     # const for /
  c_eq:   .asciiz "="     # const for =
  c_no:   .asciiz "n"     # const for n
  
          .text
          .globl main
  main:   li $v0, 4               # syscall 4, print string
          la $a0, welc            # give argument: string
          syscall                 # actually print string
  
  calc:   la $t6, remain          # load remainder variable
          move $t6, $zero         # store 0 in remainder (reset)
  
          li $v0, 4               # syscall 4, print string
          la $a0, p_int           # give argument: string
          syscall                 # actually print string
  
          li $v0, 5               # tell syscall we want to read int 1
          syscall                 # actually read in int 1
          la $s1, int1            # load int1 into $s1
          move $s1, $v0           # copy the integer from $v0 to int1
  
          li $v0, 4               # syscall 4, print string
          la $a0, p_int           # give argument: string
          syscall                 # actually print string
  
          li $v0, 5               # tell syscall we want to read int 2
          syscall                 # actually read in int 2
          la $s2, int2            # give $s2 the address to hold int 2
          move $s2, $v0           # copy the integer from $v0 to $s2
  
          li $v0, 4               # syscall 4, print string
          la $a0, p_op            # give argument: string
          syscall                 # actually print string
  
          li $v0, 8               # tell syscall we want to read operator
          la $a0, op              # give $a0 the address to hold the operator
          syscall                 # actually read in operator
  
          lb $t0, op              # load the first byte of op
          li $t1, '+'             # load const for plus
          li $t2, '-'             # load const for minus
          li $t3, '*'             # load const for multiplying
          li $t4, '/'             # load const for dividing
  
          la $s0, out             # load out to $s0
  
          beq $t0, $t1, plus      # we're adding
          beq $t0, $t2, minus     # we're subtracting
          beq $t0, $t3, multi     # we're multiplying
          beq $t0, $t4, divi      # we're dividing
          # else
          j error                 # incorrect input
  
  plus:   add $s0, $s1, $s2       # add our ints, store in $t0
          j print
  
  minus:  sub $s0, $s1, $s2       # subtract our ints, store in $t0
          j print
  
  multi:  slt $t1, $t2, $s2       # if our counter is less than int2, set $t1 to 1
          beq $t1, $zero, print   # if we've reached int2, we're done
          add $s0, $s1, $s1       # add int1 and int1, store in out
          j multi                 # loop
  
  divi:   la $t0 remain           # load remainder into $t0
          move $t0, $s1           # set remainder to dividend
          add $s0, $zero, $zero   # set out to 0, just in case
  loop:   slt $t1, $t0, $s2       # if remainder is less than divisor, set 1
          beq $t1, $zero, print   # if we're done branch to done
          sub $t0, $t0, $s2       # sub divisor from remainder, store in remainder
          addi $s0, $s0, 1        # increment quotient by 1
          j loop                  # loop
  
  print:  li $v0, 1               # tell syscall we want to print int
          la $a0, int1            # give syscall int1 to print
          syscall                 # actually print int
          li $v0, 4               # tell syscall we want to print string
          lb $a0, op              # tell syscall we want to print operator
          syscall                 # actually print string
          li $v0, 1               # tell syscall we want to print int
          la $a0, int2            # give syscall int2 to print
          syscall                 # actually print int
          li $v0, 4               # tell syscall we want to print string
          la $a0, c_eq            # tell syscall we want to print operator
          syscall                 # actually print string
          li $v0, 1               # tell syscall we want to print integer
          la $a0, out             # give syscall our output
          syscall                 # actually print int
          la $t0, remain          # load remainder
          beq $t0, $zero, again   # if we have no remainder, finish printing
          li $v0, 4               # tell syscall we want to print string
          la $a0, rmndr           # tell syscall we want to print remainder string
          syscall                 # print "r: "
          li $v0, 1               # tell syscall we want to print int
          la $a0, remain          # give syscall our remainder to print
          syscall                 # print remainder
  
  again:  li $v0, 4               # tell syscall we want to print string
          la $a0, new_line        # tell syscall to print new line
          syscall
          la $a0, again_str       # load prompt for again string for syscall
          syscall
          li $v0, 8               # tell syscall we want to read string
          la $a0, a_char          # tell syscall to put it in $a0
          syscall
          lb $t0, a_char
          li $t1, 'n'             # get n char so we can compare
          beq $t0, $t1, exit      # if we are done, exit
          #else loop
          j calc                  # jump to beginning
  
  
  
  error:  li $v0, 4               # tell syscall we want to print string
          la $a0, i_err           # give syscall what to print
          syscall                 # actually print
          j again                 # go to prompt for retry
  
  exit:   li $v0, 10              # exit code
          syscall                 #exit!
  </code></pre>
  
  <p><a href="http://i.stack.imgur.com/LkGzV.png" rel="nofollow">screenshot</a></p>