【问题标题】:MIPS: fetch address not aligned on word boundary 0x400fffffMIPS:获取地址未在字边界 0x400fffff 上对齐
【发布时间】:2016-08-06 21:03:42
【问题描述】:

我正在编写一个 mips 程序来计算指数,但得到一个错误:

Runtime exception at 0x00400158: fetch address not aligned on word boundary 0x400fffff

有什么想法吗?

问题线是lw $v0, 0($t0) # $v0 = rev_binary[idx]

              .data

prompt1:   .asciiz "Enter a base: "

prompt2:   .asciiz "Enter an exponential: "
     b:   .word 0
     e:   .word 0
rev_binary:   .word 0
     i:   .word 0
result:   .word 1


          .text
main: 
          la     $a0, prompt1            # print prompt1
          addi   $v0, $0, 4
          syscall
          addi   $v0, $0, 5              # read b
          syscall
          move   $t0, $v0                # $t0 = b

          la     $a0, prompt2            # print prompt2
          addi   $v0, $0, 4
          syscall
          addi   $v0, $0, 5              # read e
          syscall
          move   $t1, $v0                # $t1 = e


          addi   $sp, $sp, -8            # 2 * 4 = 8 bytes 
          sw     $t1, 4($sp)
          sw     $t0, 0($sp)

          jal    power

          move   $a0, $v0
          addi   $v0, $0, 1
          syscall                      # print the return value

          j      end

power:
          # save $ra and $fp
          addi   $sp, $sp, -8
          sw     $ra, 4($sp)
          sw     $fp, 0($sp)

          #copy $sp to $fp
          addi   $fp, $sp, 0

          # allocate local variables
          addi   $sp, $sp, -20

          # save $sp into $fp
          move   $fp, $sp

          #rev_binary = [ 0 ] * e
          lw     $a0, 32($sp)
          sll    $a0, $a0, 2           # $a0 = 4 * e(e << 2)
          addi   $a0, $a0, 4           # $a0 = 4 * e + 4
          addi   $v0, $0, 9            # $v0 = 9
          syscall                      # allocate memory

          sw     $v0, 0($sp)
          lw     $t0, 32($sp)          # $t0 = e
          sw     $t0, 0($v0)           #store the size of rev_binary
          sw     $0, 4($sp)

while0:
          # while e != 0      
          lw         $t0, e                # $t0 = e
          beq        $t0, $0, while0_end    # break if e == 0

           # e_half = e >> 1

          lw         $t0, 32($sp)         # allocate e_half
          srl        $t1, $t0, 1           # $t1 = $t0 >> 1
          sw         $t1, 8($sp)           # e_half = $t1

           # rev_binary[i] = e - 2 * e_half

          lw         $t0, 8($sp)           # $t0 = e_half
          sll        $t0, $t0, 1           # $t0 = e_half * 2
          lw         $t1, e                # $t1 = e
          sub        $t0, $t1, $t0         # $t0 = e - e_half * 2

          lw         $t1, 4($sp)           # $t1 = i
          sll        $t1, $t1, 2      
          addi       $t1, $t1, 4           # $t1 = i * 4 + 4
          lw         $t2, rev_binary       # $t3 = the address of rev_binary
          add        $t1, $t1, $t2         # $t1 = the address of rev_binary[i]
          sw         $t0, 0($t1)           # rev_binary[i] = $t0

           # i += 1 

          lw         $t0, 4($sp)           # $t0 = i
          addi       $t0, $t0, 1           # $t0 += 1
          sw         $t0, 4($sp)           # i = $t0

           # e = e_half

          lw         $t0, 8($sp)           # $t0 = e_half
          sw         $t0, 32($sp)          # e = $t0

          addi       $sp, $sp, 4           # release local variable n_half

          j          while0        

while0_end:   
           # rev_binary = rev_binary[:i] 

           lw         $t0, 0($sp)           # $t0: the address of rev_binary
           lw         $t1, 4($sp)           # $t1 = i
           sw         $t1, 0($t0)           # set the size of rev_binary to i


           # result = 1
           addi       $t0, $0, 1            # $t0 = 1
           sw         $t0, 12($sp)          # result = $t0



           # for j in range(i - 1, -1, -1):

           addi       $sp, $sp, -4          # allocate j
           lw         $t0, i                # $t0 = i
           addi       $t0, $t0, -1          # $t0 -= 1
           sw         $t0, 0($sp)           # j = $t0 = i - 1

           # idx = len(rev_binary) - 1
           lw         $t0, 4($sp)           # $t0 = i = len(rev_binary)
           addi       $t0, $t0, -1          # $t0 -= 1
           sw         $t0, 16($sp)          # idx = $t0

while1:       # while idx >= 0
           lw         $t0, 16($sp)          # idx = $t0
           blt        $t0, $0, while1_end  # break if idx < 0

           # result = result * result
           lw         $t0, 12($sp)        # t0 = result
           mul        $t0, $t0, $t0
           sw         $t0, 12($sp)        # $t0 = result

           # if rev_binary[idx] 
           lw         $t0, 16($sp)        # $t0 = idx
           sll        $t0, $t0, 2         # $t0 = idx * 4
           addi       $t0, $t0, 4         # $t0 = idx * 4 + 4
           lw         $t1, 0($sp)         # $t1 = the address of rev_binary
           add        $t0, $t1, $t0       # $t0 = the address of rev_binary[idx]
           lw         $v0, 0($t0)         # $v0 = rev_binary[idx]

if:            
           beq        $t0, $0, end_if     # end if if (idx == 0)

           # result = result * b
           lw         $t0, 12($sp)        # $t0 = result
           lw         $t1, 28($sp)          # $t1 = b
           mul        $t0, $t0, $t1         # $t0 = $t0 * $t1
           sw         $t0, 12($sp)          # result = $t0

end_if:

         # idx = idx - 1

         lw         $t0, 16($sp)           # $t0 = idx
         addi       $t0, $t0, -1           # $t0 -= 1
         sw         $t0, 16($sp)           # idx = $t0

         j       while1                   # loop

while1_end:
         lw         $v0, 12($sp)           # $v0 = result

         lw         $t0, 20($sp)           # reset old $fp
         move       $fp, $t0
         lw         $t0, 24($sp)           # reset old $ra
         move       $ra, $t0

         addi       $sp, $sp, 36           # release local variables

         jr         $ra # return


end:
         # exit

【问题讨论】:

  • 您无法从未对齐的地址中读取单词。地址看起来也不正确,值真的正确吗?没有从堆栈中读取错误的值?

标签: mips mars-simulator


【解决方案1】:

您只能从对齐的地址加载单词。该地址看起来也很奇怪,因为它最后有 0xffff。

查看你拥有的代码

lw         $t1, 0($sp)         # $t1 = the address of rev_binary

但在此之前您将j 存储到(0)$sp,因此不能包含rev_binary 的地址。也许你需要

la         $t1, rev_binary         # $t1 = the address of rev_binary

改为?

【讨论】:

  • 你的意思是la $t1, rev_binary
猜你喜欢
  • 2016-08-24
  • 2017-06-25
  • 2014-05-27
  • 2012-03-05
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多