2017-03-08 83 views
2

我希望你们都有美好的一天。我希望我能得到我的项目代码的一些帮助。基本上是一句“渐行渐远”。在提示时键入,然后键入搜索词“FADED”,执行代码以查看单词“FADED”是否在句子中,如果是,则表示“找到匹配”并且if不是“找不到匹配”。那么当我编译并运行它给我一个“行65:运行时异常在0x00400098:地址超出范围0x00000000”错误,并且有多条线路有此错误。任何人都可以帮助我吗?过去3天我一直试图做,最后得到一些帮助......如果您有任何问题,请让我知道!需要帮助搜索在MIPS中的句子中的单词

.data 

str: .space 100     # Pre Allocate space for the input sentence 
input: .space 30    # Pre Allocate space for the input sentence 
ins: .asciiz "Please enter a sentence: " # string to print sentence 
seek: .asciiz "Please enter a word: "  # string to print sentence 
nomatch: .asciiz "No Match(es) Found"   
found: .asciiz " Match(es) Found" 
newline: .asciiz "\n"    # string to print newline 

.text 

li $v0, 4  # syscall to print string 
la $a0, ins  # move str into a0 
syscall   # syscall 

li $a1, 100  # allocate space for the string 
la $a0, str  # load address of the input string 
li, $v0, 8  # read string input from user 
syscall   # issue a system call 

move $t9, $a0  # move string to t5 

li $v0, 4  # syscall to print string 
la $a0, seek  # move str into a0 
syscall   # syscall 

la $a0, input  # load address of the input string 
li $a2, 30  # allocate space for the string 
li, $v0, 8  # read string input from user 
syscall   # issue a system call 

move $t8, $a0  # move string to t8 
la $s5, input  # create space for the input word we are looking for in s5 

wloop:   # loop to allocate space for the word we are looking for to a register 
lb $t0, 0($t8)  # load first character into t0 
beqz $t0, sentence # branch to sentence loop if null character 
sb $t0, 0($s5)  # store the current character into current address of s5 
addi $t8, $t8, 1 # add one to t8 to move to next character 
addi $s5, $s5, 1 # add one to s5 to move to the next allocated space 
j wloop   # jump back to wloop 

la $s4, str  # create space for the input sentence 

sentence:  # loop to allocate space for the word we are looking for into a register 
lb $t0, 0($t9)  # load first character into t0 
beqz $t0, resetsen # branch to check loop if null character 
sb $t9, 0($s4)  # store the current character into current address of s4 
addi $t9, $t9, 1 # add one to t9 to move to next character 
addi $s4, $s4, 1 # add one to s5 to move to the next allocated space 
j sentence  # jump back to sentence 

resetsen: 
li $s4, 0  # reset sentence back to 0 (first character) 

resetword: 
li $s5, 0  # reset word we are looking for back to 0 (first character) 

check: 
lb $t1, 0($s4)  # load current character of sentence to t1 
beq $t1, 46, quit # branch to QUIT if period found 
bne $t1, 70, nextword # if t1 != t0 branch to nextword 
beq $t1, 70, checkword # branch to found if t1 = f 

nextword:  # loop to get to the next word 
lb $t1, 0($s4)  # load current character to t1 
beq $t1, 46, quit # branch to quit if period found 
bne $t1, 32, increment # if current character is not a spaace branch to increment 
beq $t1, 32, plusone # if current character is a space branch to plusone 
increment:  # increment procedure 
addi $s4, $s4, 1 # add one to s4 to move to next character 
j nextword  # jump to nextword 
plusone:  # plusone procedure 
addi $s4, $s4, 1 # add one to s4 to move to next character 
j resetword  # jump to check 

checkword: 
addi $s4, $s4, 1 # add one to s4 to move to next character 
addi $s5, $s5, 1 # add one to s5 to move to next character 
lb $t1, 0($s4)  # load current character of sentence to t1 
lb $t0, 0($s5)  # load current character of sentence to t0 
bne $t1, $t0, increment # if t0 != t1 branch to increment (looking for a) 
addi $s4, $s4, 1 # add one to s4 to move to next character 
addi $s5, $s5, 1 # add one to s5 to move to next character 
lb $t1, 0($s4)  # load current character of sentence to t1 
lb $t0, 0($s5)  # load current character of sentence to t0 
bne $t1, $t0, increment # if t0 != t1 branch to increment (looking for d) 
addi $s4, $s4, 1 # add one to s4 to move to next character 
addi $s5, $s5, 1 # add one to s5 to move to next character 
lb $t1, 0($s4)  # load current character of sentence to t1 
lb $t0, 0($s5)  # load current character of sentence to t0 
bne $t1, $t0, increment # if t0 != t1 branch to increment (looking for e) 
addi $s4, $s4, 1 # add one to s4 to move to next character 
addi $s5, $s5, 1 # add one to s5 to move to next character 
lb $t1, 0($s4)  # load current character of sentence to t1 
lb $t0, 0($s5)  # load current character of sentence to t0 
bne $t1, $t0, increment # if t0 != t1 branch to increment (looking for d) 
addi $t2, $t2, 1 # add one to t2 which counts occurences 
j resetword 

quit: 
beqz $t2, exit  # if t2 = 0 branch to exit 
li $v0, 1  # syscall to print integer 
move $a0, $t2  # move str into a0 
syscall   # syscall 
li $v0, 4  # syscall to print string 
la $a0, found  # move found into a0 
syscall   # syscall 
j endprogram 

exit: 
li $v0, 4  # syscall to print string 
la $a0, nomatch  # move nomatch into a0 
syscall   # syscall 

endprogram: 
li $v0, 10 
syscall 
+0

哪条线是65线?据推测它使用了一个糟糕的指针。反过来看看为什么那个指针没有正确的值。另外,使用调试器单步执行代码。 – Jester

+0

不太可能。更可能的是'lb $ t1,0($ s4)#将句子的当前字符加载到t1',因为你在那里使用'$ s4'作为指针,但是你早先将它清零:'li $ s4,0#将句子重置为0(第一个字符)'。你可能想要'la $ s4,str'来代替。 – Jester

+0

使用调试器单步执行代码并查看它不在您想要的位置。 – Jester

回答

1

你在地方有一些很好的结构。

但是,在许多地方,评论与代码不匹配(例如,您正在做一堆剪切粘贴)。而且,虽然我意识到你刚刚开始,但很多侧边栏评论只是回顾了asm指令。 (EG):

addi $s4, $s4, 1 # add one to s4 to move to next character 

这将有助于你与你的理解,如果意见跟着算法:

addi $s4, $s4, 1 # point to next character 

另一个问题是,checkloop:实际上应该包含一个循环,而不是bne insts对于固定数量。

除了顶部注释块中其他人提到的一些问题之外,其中一个重要问题是您要重置句子/字符串指针。你真正需要的是另一个指针[增加1],可以记住句子中“停止的位置”,然后重新启动内部循环(即checkloop:

尽管我试图保留尽可能多的代码,可能,我不得不重构一下。我使用的一个“技巧”是创建一个函数,提示用户,读取缓冲区,然后将句号和换行符转换为空格[这使得扫描循环变得更容易]

无论如何,这里是[please pardon无偿款式清理]:

.data 
str:  .space  100   # space for sentence 
input:  .space  30   # space for word to scan for 

ins:  .asciiz  "Please enter a sentence: " 
seek:  .asciiz  "Please enter a word: " 
nomatch: .asciiz  "No Match(es) Found" 
found:  .asciiz  " Match(es) Found" 
newline: .asciiz  "\n" 
quo1:  .asciiz  "'" 
quo2:  .asciiz  "'\n" 

    .text 
    .globl main 
# registers: 
# t0 -- current char from string 
# t1 -- current char from word 
# t4 -- space char 
# t5 -- pointer to current char in word to scan for 
# t6 -- pointer to current char in string for given pass 
# t7 -- pointer to start of scan in string ("where we left off") 
# t8 -- word match count 
main: 
    # read sentence 
    la  $a0,ins     # prompt 
    la  $a1,100     # length of buffer 
    la  $a2,str     # buffer address 
    jal  rdstr 

    # read scan word 
    la  $a0,seek    # prompt 
    la  $a1,30     # length of buffer 
    la  $a2,input    # buffer address 
    jal  rdstr 

    la  $t7,str     # pointer to first char in string 
    li  $t8,0     # zero the match count 

strloop: 
    move $t6,$t7     # start scan where we left off in string 
    la  $t5,input    # start of word to scan for 
    li  $t4,0x20    # get ascii space 

wordloop: 
    lbu  $t0,0($t6)    # get char from string 
    addiu $t6,$t6,1    # advance pointer within string 

    lbu  $t1,0($t5)    # get char from scan word 
    addiu $t5,$t5,1    # advance pointer within scan word 

    bne  $t0,$t1,wordfail  # char mismatch? if yes, fly 
    bne  $t1,$t4,wordloop  # at end of scan word? if no, loop 

    addi $t8,$t8,1    # increment match count 

wordfail: 
    addiu $t7,$t7,1    # advance starting point within string 
    lbu  $t0,0($t7)    # get next char in sentence 
    bnez $t0,strloop    # end of sentence? if no, loop 

    beqz $t8,exit    # any match? if no, fly 
    li  $v0,1     # syscall to print integer 
    move $a0,$t8     # print match count 
    syscall 

    li  $v0,4     # syscall to print string 
    la  $a0,found    # move found into a0 
    syscall 
    j  endprogram 

exit: 
    li  $v0,4     # syscall to print string 
    la  $a0,nomatch    # move nomatch into a0 
    syscall 

endprogram: 
    li  $v0,10 
    syscall 

# rdstr -- read in and clean up string (convert '.' and newline to space) 
# 
# arguments: 
# a0 -- prompt string 
# a1 -- buffer length 
# a2 -- buffer address 
# 
# registers: 
# t0 -- current character 
# t1 -- newline char 
# t2 -- ascii period 
# t3 -- ascii space 
rdstr: 
    # prompt user 
    li  $v0,4     # syscall to print string 
    syscall 

    # get the string 
    move $a0,$a2     # get buffer address 
    li  $v0,8     # read string input from user 
    syscall       # issue a system call 

    li  $t1,0x0A    # get ascii newline 
    li  $t2,0x2E    # get ascii dot 
    li  $t3,0x20    # get ascii space 

    # clean up the string so the matching will be easier/simpler 
rdstr_loop: 
    lbu  $t0,0($a0)    # get character 

    beq  $t0,$t1,rdstr_nl  # fly if char is newline 
    beq  $t0,$t2,rdstr_dot  # fly if char is '.' 

rdstr_next: 
    addiu $a0,$a0,1    # advance to next character 
    j  rdstr_loop 

rdstr_dot: 
    sb  $t0,0($a0)    # replace dot with space 
    j  rdstr_loop 

rdstr_nl: 
    sb  $t3,0($a0)    # replace newline with space 

    j  rdstr_done    # comment this out to get debug print 

    # debug print the cleaned up string 
    li  $v0,4     # output string 
    la  $a0,quo1    # output a quote 
    syscall 
    move $a0,$a2     # output the cleaned up string 
    syscall 
    la  $a0,quo2 
    syscall 

rdstr_done: 
    jr  $ra      # return