0

我正在尝试将 MIPS 代码转换为 ARM 代码,这不是问题,因为我遇到了一个棘手的异常,我希望有人能解释什么是错误的以及如何处理它。程序传递 a0,它是指向 mips 二进制指令表示的指针,它返回 $v0 创建的 ARM 指令的数量和 $v1 - 指向第一条 arm 指令的指针。test.s(ta 用来测试的代码)然后执行一些操作来测试程序是否成功。如果你愿意,我可以给你看 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
4

1 回答 1

1

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

于 2012-11-30T23:22:12.120 回答