2013-11-09 32 views
2

我写一个简单的MIPS汇编代码遍历字符串由C环路转换为MIPS汇编语言(无效地址错误)

的角色,并认为一个给定的子实例..

第一,C代码:

for (i=0; i<length(text)-length(sub_string); i++) { 

    match = TRUE 

    for (j=0; j<length(sub_string); j++) 
     if (text[i+j] != sub_string[j]) { 
      match = False; 
      break; 
     } 
} 


这是我的MIPS代码的一部分。

.text 

# a0: text 
# a1: substring 
# v0: count 
myfunction: 
    move $s0, $ra 

    move $a2, $a0 
    jal strlen 
    move $t1, $v1   # text_len 

    move $a2, $a1 
    jal strlen 
    move $t2, $v1   # substring_len 

    sub $t1, $t1, $t2  # text_len - substring_len 

    li $t0, 0    # i = 0 

    j i_test 



i_body: 
    li $t3, 1 # match = TRUE 
    li $t4, 0 # j = 0 

    j j_test 

i_test: 
    blt $t0, $t1, i_body 
    move $ra, $s0 
    jr $ra 



j_body: 
    add $t6, $a0, $t0  # &text[i] 
    add $t6, $t6, $t4  # &text[i+j] 
    lb $t6, 0($t6)   # text[i+j] 

    add $t7, $a1, $t4  # &sub_string[j] 
    lb $t7, 0($t7)   # sub_string[j] 

    beq $t6, $t7, j_skip # if (text[i+j] == sub_string[j]) 

    # if (text[i+j] != sub_string[j]) 
    li $t3, 0    # match = FALSE 
    j j_break    # break 

j_test: 
    blt $t4, $t2, j_body 

j_skip: 
    addi $t4, $t4, 1 # j++ 
    j j_body 

j_break: 
    addi $t0, $t0, 1 # i++ 
    j i_body 



strlen: 
    li $v1, 0   # i = 0 
    b strlen_test 
strlen_body: 
    addi $v1, $v1, 1 # len++ 
strlen_test: 
    add $t0, $a2, $v1   # &str[i] 
    lb $t0, 0($t0)    # str[i] 
    bne $t0, $0, strlen_body # loop 
    jr $ra 




.globl main 
main: 

    la $a0, text1 
    la $a1, substring1 
    jal myfunction 
    la $a0, text1 
    jal print_string 

    li $v0, 10   # Exit 
    syscall 


print_string: 
      li $v0, 4 
      syscall 
      la $a0, newline 
      li $v0, 4 
      syscall 
      jr $ra 


.data 
text1:  .asciiz "Hello, world!" 
substring1: .asciiz "lo" 

newline: .asciiz "\n" 


然而,当我运行此代码,我越来越坏

地址错误的死循环:


Exception occurred at PC=0x00400070             
Bad address in data/stack read: 0x10021778                               
    Exception 7 [Bad address in data/stack read] occurred and ignored                          
Exception occurred at PC=0x00400078                                  
    Bad address in data/stack read: 0x10021786                                
    Exception 7 [Bad address in data/stack read] occurred and ignored                          
Exception occurred at PC=0x00400070                                  
    Bad address in data/stack read: 0x10021779                                
    Exception 7 [Bad address in data/stack read] occurred and ignored                          
Exception occurred at PC=0x00400078                                  
    Bad address in data/stack read: 0x10021787                                
    Exception 7 [Bad address in data/stack read] occurred and ignored                          
Exception occurred at PC=0x00400070                                  
    Bad address in data/stack read: 0x1002177a                                
    Exception 7 [Bad address in data/stack read] occurred and ignored                          
Exception occurred at PC=0x00400078                                  
    Bad address in data/stack read: 0x10021788                                
    Exception 7 [Bad address in data/stack read] occurred and ignored                          
Exception occurred at PC=0x00400070                                  
    Bad address in data/stack read: 0x1002177b                                
    Exception 7 [Bad address in data/stack read] occurred and ignored                          
Exception occurred at PC=0x00400078                                  
    Bad address in data/stack read: 0x10021789                                
    Exception 7 [Bad address in data/stack read] occurred and ignored    


我意识到错误的地址错误来自于第3行和第5行

j_body(加载字节指令)。我初始化字符串的地址,所以我不知道这是为什么

发生......

这里是我的问题:

  1. 为什么我会得到这个无限循环? (我以为我已经正确实现了for和for循环for i和j)

  2. 为什么我得到一个错误的地址错误?

谢谢:)

回答

2
j_test: 
    blt $t4, $t2, j_body 

j_skip: 
    addi $t4, $t4, 1 # j++ 
    j j_body 

j_break: 
    addi $t0, $t0, 1 # i++ 
    j i_body 

你不是应该跳到j_break如果j_test条件不满足?现在编写这段代码的方式是继续执行“j循环”的主体,即使j >= strlen(substring)

此外,j i_bodyj_break:大概应该是j i_test(你增加i,所以你会想,如果条件检查的“i循环”仍是如此)。

+0

change j i_body到j i_test解决了我的问题:)))))你是最好的! – user2492270

1

在j_body,您使用$ T7都存储STR(I + J),和sub_str(J);然后通过比较beq $ t7,$ t7,j_body来决定是否退出j_body(无论如何,该指令总是会评估为真,并且使其成为无限循环)。将sub_str(j)中的字节存储在$ t8中,并将beq行更改为比较$ t7和$ t8。

可能还有更多;但这绝对必须改变。在更正此问题后,我建议运行,并更新您遇到的任何新错误。

+0

awww对不起(这是一个错字...现在我比较$ t6和$ t7,但得到相同的无限错误。谢谢指出我愚蠢的错误 – user2492270

+0

但现在你不会跳回来,在平等的情况下,转到j_body(j_skip),我认为跳到j_body是正确的,减去错字 – gnometorule

+0

另外,@迈克尔是常驻大会的人之一,所以可能也会调整他发现的内容 – gnometorule