2016-04-15 42 views
0

我正在写一个MIPS程序来计算指数不对齐的地址,但得到一个错误:MIPS:取上字边界0x400fffff

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

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

回答

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 

改为?

+0

你的意思是'la $ t1,rev_binary'? –

+0

@KonradLindenbach当然可以。谢谢! –