MIPS汇编程序ERROR Exception 4 [inst / data fetch中的地址错误]

时间:2012-11-30 22:19:23

标签: mips

我正在尝试将MIPS代码转换为ARM代码,这不是一个问题,我得到了一个非常例外我希望有人可以解释什么是错的以及如何处理它。程序传递a0,它是指向mips二进制指令表示的指针,它返回$ v0创建的ARM指令的数量和$ v1 - 指向第一个arm指令的指针。 test.s(t.a.用于测试的代码)然后执行一些操作来测试程序是否成功。我可以告诉你test.s如果你愿意。无论如何,我一直得到的错误是以下......

  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 < 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

1 个答案:

答案 0 :(得分:1)

您正在读取或写入或分支到非32位对齐的位置。不正确的指令从地址0x00400140开始,从程序开始可能是0x140字节。尝试在debugger中运行代码,并在地址0x00400140处放置断点。