title: MIPS assembly program ERROR Exception 4 [Address error in inst/data fetch]
body: <p>I am trying to convert MIPS code into ARM code, this is not an issue its that I am getting a  gnarly exception I'm hoping someone can explain whats wrong and what to do about it. the program is passed a0 which is a pointer to the mips binary instruction representations and it returns $v0 the number of ARM instruction created and $v1 - a pointer to the first arm instruction. test.s (code the t.a. uses to test) then performs some actions to test if the programs succeeded. I could show you test.s if you'd like. anyway the error I keep getting is the following...</p>
  
  <pre><code>  Exception occurred at PC=0x00400140
     Unaligned address in inst/data fetch: 0xfffffffb
     Exception 4  [Address error in inst/data fetch]  occurred and ignored
    Exception occurred at PC=0x00400144
     Unaligned address in inst/data fetch: 0xfffffff7
     Exception 4  [Address error in inst/data fetch]  occurred and ignored
    Read from unused memory-mapped IO address (0xfffffff4)
  
  
      .data
      .align 2
  mipsArray:      .word 0
  mipsToArm:      .word 0
  branchTable:        .word 0
  armArray:           .word 0
  # endConditon:      .word 0xFFFFFFFF
      .text
  #----------------------------------------------------------------------#
  # Current Register list:
  #   $t0 - is initially used as a pointer to the mipsArray
  #   $a0 - holds the pointer to the first word of the mips array
  #   $s1 - will hold the current word as we check for FFFFFFFF
  #   $s8 - will hold the check value 0xFFFFFFFF
  #----------------------------------------------------------------------#
  MIPStoARM:
      addi        $sp, $sp, -4        # prep the frame
      sw      $fp, 0($sp)     # prep the frame
      move    $fp, $sp        # prep the frame
      addi        $sp, $sp, -36       # prep the frame
      sw      $ra, -4($fp)        # prep the frame
      sw      $s8, -8($fp)        # prep the frame
      sw      $s1, -12($fp)       # prep the frame
      sw      $s2, -16($fp)       
      sw      $s3, -20($fp)
      sw      $s4, -24($fp)
      sw      $s5, -28($fp)
      sw      $s6, -32($fp)
      sw      $s7, -36($fp)
      la      $t0, mipsArray      # store the pointer into data as a global   
      sw      $a0, 0($t0)
      li      $s8, 0xFFFFFFFF # this is the check value
      addi        $t1, $0, 1      # for now t1 is the counter = 1
      lw      $s1, 0($a0)
   countLoop:
      beq     $s1, $s8, allocateSpace # if word == FFFFFFFF then allocate the      space
      add     $a0, $a0, 4 # move to next word
      lw      $s1, 0($a0)
      addi        $t1, $t1, 1 # counter++
      j       countLoop
   allocateSpace:
      sll     $t1, $t1, 2 # count * 4 to get number of words
      li      $v0, 9
      add     $a0, $0, $t1
      syscall
      move        $t2, $v0        # t2 now holds the pointer to the beginning of the allocated space
      la      $t0, mipsToArm
      sw      $t2, 0($t0) # now mipstoarms first element is the pointer to the allocated space
      li      $v0, 9
      syscall
      move        $t2, $v0        # t2 now holds the pointer to the beginning of the allocated space
      la      $t0, branchTable
      sw      $t2, 0($t0) # now branchTable first element is the pointer to the allocated space
      sll     $t1, $t1, 1 # now multiply the counter by 2 to make enough space for armArray
      li      $v0, 9
      add     $a0, $0, $t1
      syscall
      move    $t2, $v0
      la      $t0, armArray
      sw      $t2, 0($t0) # now armArray first element is the pointer to the allocated space
   #--------------------------------------------------------------------#
   # from this point on should be the translation mips to arm 
   # first load the first word then
   # th e main switch case which checks opcode
   #
   # notes on current register usage:
   #  s1 - points to the mips binary data
   #  s2 - points to the mips to arm 
   #  s3 - points to the branch table
   #  s4 - points to the arm array 
   #  s5 - this boyo is gonna count how many arm instructions there are
   #  s8 - 0xFFFF FFFF
   #  t0 - is temp used to loading double pointers
   #  t2 - will hold the current word like a boss
   #---------------------------------------------------------------------#
  wordSetup:
       la     $t0, mipsArray          #loads the address of mipsarray which first word conains the pointer
       lw     $s1, 0($t0)             # load the pointer
       la         $t0, mipsToArm
       lw     $s2, 0($t0)
       la     $t0, branchTable
       lw     $s3, 0($t0)
       la         $t0, armArray
       lw     $s4, 0($t0)
       lw     $t2, 0($s1)         # t2 should now hold the current word
       move   $s5, $0             # initialize the counter to 0
       move       $t3, $0             # initialize to 0
       beq        $t2, $s8, done          # this will have to be changed for Part2
       addi       $s5, $s5, 1         # counter++
       j      opcodeSwitch            # jump to the main switch
   nextWord:
       addi       $s1, $s1, 4         # sets the MIPS to point to next word
       lw     $t2, 0($s1)
       addi       $s2, $s2, 4         # points to next word in MIPStoARM
       addi       $s3, $s3, 4         # points to next word in branctable
       beq        $t2, $s8, done      # if the current word is 0xFFFFFFFF your done part 1
   opcodeSwitch:
       # first step here is to mask out the 6 most significant bits
       li     $t6 0xFC000000
       and        $t3, $t2, $t6           # mask out opcode save into t3
       beq        $t3, $0, zeroOpHandler  # checks if the opcode is 000000
       li     $t6, 0x04000000
       beq        $t3, $t6, oneOpHandler  # checks if the opcode is 000001
       li     $t6, 0x10000000
       beq        $t3, $t6, fourOpHandler # checks if the opcode is 000100
       li     $t6, 0x20000000
       beq        $t3, $t6, eightOpHandler    # checks if the opcode is 001000
       li         $t6, 0x30000000
       beq        $t3, $t6, cOpHandler    # checks if the opcode is 001100
       li     $t6, 0x34000000
       beq        $t3, $t6, dOpHandler    # checks if the opcode is 001101
   #---------------------------------------------------------------------#
   # ~~~zeroOpHandler:
   #---------------------------------------------------------------------#
   zeroOpHandler:
       li     $t6, 0x001FFFFF
       and        $t3, $t2, $t6
       li     $t6, 0x00000008
       beq        $t3, $t6, jRHandler
       andi       $t3, $t2, 0x7FF
       li     $t6, 0x024          # this should represent the AND func.
       beq        $t3, $t6, oaasHandler   # if it matches go to oaasHandler
       li     $t6, 0x025          # this should represent the OR func.
       beq        $t3, $t6, oaasHandler       # if it matches go to orHandler
       li     $t6, 0x020          # this should represent the ADD func.
       beq        $t3, $t6, oaasHandler   # if it matches go to oaasHandler   
       li     $t6, 0x022          # this should represent the SUB func.
       beq        $t3, $t6, oaasHandler   # if it matches go to oaasHandler
       li     $t6, 0x006          # this should represent the SRLV func.
       beq        $t3, $t6, srlvHandler   # if it matches go to srlvHandler
       li     $t6, 0x004          # this should represent the SLLV func.
       beq        $t3, $t6, sllvHandler   # if it matches go to sllvHandler   
       andi       $t3, $t2, 0x3F
       li     $t6, 0x03               # this should represent the SRA func.
       beq        $t3, $t6, sraHandler    # if it matches go to sraHandler
       li     $t6, 0x02               # this should represent the SRL func.
       beq        $t3, $t6, srlHandler    # if it matches go to srlHandler
       li     $t6, 0x00               # this should represent the SLL func.
       beq        $t3, $t6, sllHandler    # if it matches go to sllHandler    
   #---------------------------------------------------------------------#
   oneOpHandler:
   fourOpHandler:
   eightOpHandler:
   cOpHandler:
   dOpHandler:
   ######
   srlvHandler:
   sllHandler:
   sllvHandler:
   srlHandler:
   sraHandler:
  
  #---------------------------------------------------------------------#
  # ~~~AND HANDLER
  #---------------------------------------------------------------------#
  oaasHandler:
  #this handles or, and, sub, add.
      li      $s6, 0xE0000000
      li      $t6, 0x03E00000
      and     $t3, $t6, $t2       # mask out s register   
      srl     $t3, $t3, 5     # move s into the corresponding spot for ARM
      li      $t6, 0x001D0000 # set t6= 29 in position
      bne     $t3, $t6, oRnSecCheck
      li      $s6, 0xE00D0000 # if it is == then set rn in arm to 13
      j       oaasRmReg           
   oRnSecCheck:
      li      $t6, 0x001F0000
      bne     $t3, $t6, oRnThirdCheck
      li      $s6, 0xE00E0000
      j       oaasRmReg
  oRnThirdCheck:
       li     $t6, 0x000D0000
       slt        $t6, $t3, $t6
       bne        $t6,    $0, oRnNoRegTrans
       # set instruction to MOV R0 R0
       li     $s6, 0xE1B00000
       j      setTables
   oRnNoRegTrans:
       or     $s6, $s6, $t3
       j      oaasRmReg
   #-----------------------------------------------------------------#
   # this next part deals with the rm register
   #-----------------------------------------------------------------#
   oaasRmReg:
       li     $t6, 0x001F0000 # prepare the mask
       and        $t3, $t2, $t6       # mask out Rm
       srl        $t3, $t3, 16        # move s into position for arm 
       li     $t6, 0x0000001D # set t6= 29 in position
       bne        $t3, $t6, oRmSecCheck
       li     $t3, 0x0000000D # if it is == then set rn in arm to 13
       or     $s6, $s6, $t3       # set corresponding bits to 13
       j      oaasRdReg           
   oRmSecCheck:
       li     $t6, 0x0000001F
       bne        $t3, $t6, oRmThirdCheck
       li     $t3, 0x0000000E
       or     $s6, $s6, $t3       # set corresponding bits to 14
       j      oaasRdReg
   oRmThirdCheck:
       slti       $t6, $t3, 0x0000000D
       bne        $t6,    $0, oRmNoRegTrans
       # set instruction to MOV R0 R0
       li     $s6, 0xE1B00000
       j      setTables
   oRmNoRegTrans:
       or     $s6, $s6, $t3
       j      oaasRdReg
   #-----------------------------------------------------------------#
   # this next part deals with the rd register
   #-----------------------------------------------------------------#
   oaasRdReg:
       li     $t6, 0x0000F800 # prepare the mask
       and        $t3, $t2, $t6       # mask out Rm
       sll        $t3, $t3, 1     # move s into position for arm 
       li     $t6, 0x0001D000 # set t6= 29 in position
       bne        $t3, $t6, oRdSecCheck
       li     $t3, 0x0000D000 # if it is == then set rn in arm to 13
       or     $s6, $s6, $t3       # set corresponding bits to 13
       j      oaasSetOpCode           
   oRdSecCheck:
       li     $t6, 0x0001F000
       bne        $t3, $t6, oRdThirdCheck
       li     $t3, 0x0000F000
       or     $s6, $s6, $t3       # set corresponding bits to 14
       j      oaasSetOpCode
   oRdThirdCheck:
       li     $t6, 0x0000D000
       slt        $t6, $t3, $t6
       bne        $t6,    $0, oRdNoRegTrans
       # set instruction to MOV R0 R0
       li     $s6, 0xE1B00000
       j      setTables
  oRdNoRegTrans:
      or      $s6, $s6, $t3
      j       oaasSetOpCode
   oaasSetOpCode:
      # this is a switch statement similar to the main switch to set opcode
      # for oaas cases
      andi        $t3, $t2, 0x7FF
      li      $t6, 0x024          # AND
      bne     $t6, $t3, oOROpCode 
      j       setTables               # go straight to setTables because opcode = 0000
   oOROpCode:
      li      $t6, 0x00000025
      bne     $t6, $t3, oADDOpCode    # OR opcode
      li      $t3, 0x01800000
      or      $s6, $s6, $t3           # place theopcode in the arm instruction
      j       setTables
   oADDOpCode:
       li     $t6, 0x00000020     # AND opcode
       bne        $t6, $t3, oSUBOpCode    
       li     $t3, 0x00800000
       or     $s6, $s6, $t3           # place theopcode in the arm instruction
        j     setTables
   oSUBOpCode:
       #li        $t6, 0x00000022
       # here we will probably want to add a bne and maybe branch to srlv or sllv
       # once we understand how to handle them
       li     $t3, 0x00400000
       or     $s6, $s6, $t3
       j      setTables
  
   #---------------------------------------------------------------------#
   # ~~~JR HANDLERctions that we will be needing are listed below.
   #---------------------------------------------------------------------#
   jRHandler:
       move       $s7, $0             # set the branch flag to 0 (off)
       li     $t6, 0x03E00000
       and        $t3, $t6, $t2           # mask out the s register
       srl        $t3, $t3, 21            # move it to least significant bits
       li     $t6, 0x0000001D     # here we check if the register is 13
       bne        $t3, $t6, secondCheck   # if it isnt move to next check
       li     $s6, 0xE12FFF1D     # if it is this is the ARM translation store in s6
       # now we have to put the word into the arm table and save the address in the 
       # mips to arm table and set the equivalent offset in the branchtable to 0
       j      setTables
   secondCheck:
       li     $t6, 0x0000001F     
       bne        $t3, $t6, thirdCheck    # if the register isnt 31 jump to noRegTrans
       li     $s6, 0xE12FFF1E     # else this is the ARM translation
       # now we have to put the word into the arm table and save the address in the 
       # mips to arm table and set the equivalent offset in the branchtable to 0
       j      setTables
   thirdCheck:
       slti       $t6, $t3, 0xD           # check if s &lt; 13 t6 = 1 else t6 = 0
       bne        $t6, $0, noRegTrans
           li     $s6, 0xE1B00000
       j      setTables
   noRegTrans:
       li     $s6, 0xE12FFF10
       or     $s6, $s6, $t3           # or the register number into the format 
       j      setTables               # then jump to set Tables
   #-------------------------------------------------------------------#
  
  
   setTables:
       bne        $s7, $0, branchSetTables
       addi       $s4, $s4, 4
       addi       $s5, $s5, 1         # ARMcounter++
       sw     $s6, 0($s4)         # place the ARM instruction in the      ARM array
       sw     $s4, 0($s2)         # store the ARM tables address in miptoarm
       sw     $0, 0($s3)          # stores a 0 in the branch table
       j      nextWord
   branchSetTables:
   done:
      move        $v0, $s5
      la      $t0, armArray
      lw      $v1, 0($t0)
      lw  $ra, -4($fp)        # prep the frame
      lw  $s8, -8($fp)        # prep the frame
      lw  $s1, -12($fp)       # prep the frame
       lw $s2, -16($fp)       
       lw $s3, -20($fp)
       lw $s4, -24($fp)
       lw $s5, -28($fp)
       lw $s6, -32($fp)
       lw $s7, -36($fp)
       addu   $sp, $sp, 40        # pop 
       lw $fp, -4($sp)    
       jr     $ra
  </code></pre>