我希望你们都过得愉快。我希望我可以通过我的项目代码获得一些帮助。基本上是一个句子" FADED IN FADED OUT。"在提示时键入,然后搜索单词" FADED"键入并执行代码以查看单词" FADED"在句子中,如果是,它会说" x匹配发现"如果没有"找不到匹配"。好吧,当我编译并运行时,它给我一个"第65行:0x00400098处的运行时异常:地址超出范围0x00000000"错误,有多行有此错误。有人能帮我这个吗?过去3天我一直在尝试这样做,最后打破了一些帮助...如果您有任何疑问,请告诉我!
.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 :(得分:1)
你的地方有一些很好的结构。
但是,在很多地方评论与代码不匹配(例如,你正在做一堆cut-n-paste)。而且,虽然我意识到你刚刚开始,但很多你的侧栏评论只是反刍了asm指令。 (例如):
addi $s4, $s4, 1 # add one to s4 to move to next character
如果评论遵循算法,那将有助于您理解:
addi $s4, $s4, 1 # point to next character
另一个问题是checkloop:
实际上应该包含循环而不是固定数量的bne
个。
除了顶部评论块中其他人提到的一些问题之外,一个重要的问题是您正在重置句子/字符串指针。你真正需要的是另一个指针[加1],它会在句子中记住“你离开的地方”并从那里重新开始内循环(即checkloop:
)
虽然我尽可能多地保留你的代码,但我不得不重构它。我使用的一个“技巧”是创建一个提示用户,读取缓冲区,然后将句点和换行符转换为空格的函数[这使得扫描循环更加容易]
无论如何,这是[请原谅无偿的风格清理]:
.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