2017-03-08 1 views
2

J'espère que vous passez une bonne journée. J'espérais pouvoir obtenir de l'aide avec mon code de projet. Fondamentalement, une phrase "s'est estompé." est tapé à l'invite, puis un mot de recherche "FADED" est tapé et le code est exécuté pour voir si le mot "FADED" est dans la phrase et si c'est le cas, il dira "x Match (es) Found" et si pas "Aucune correspondance trouvée". Eh bien, quand je compile et exécute, il me donne une erreur "ligne 65: Exception d'exécution à 0x00400098: adresse hors plage 0x00000000" et il y a plusieurs lignes qui ont cette erreur. Quelqu'un pourrait-il m'aider avec ça? J'ai essayé de le faire au cours des 3 derniers jours et finalement cassé pour de l'aide ... Si vous avez des questions s'il vous plaît faites le moi savoir!Besoin d'aide pour chercher un mot dans une phrase dans 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

Quelle ligne est la ligne 65? Vraisemblablement, il utilise un mauvais pointeur. Travaillez en arrière pour voir pourquoi ce pointeur n'a pas la bonne valeur. En outre, utilisez un débogueur pour exécuter le code en une seule étape. – Jester

+0

Peu probable. Plus probable est 'lb $ t1, 0 ​​($ s4) # charger le caractère courant de la phrase à t1 parce que vous utilisez $ s4 comme pointeur là mais vous l'avez mis à zéro plus tôt:' li $ s4, 0 # réinitialise la phrase à 0 (premier caractère) '. Vous voudrez peut-être faire 'la $ s4, str' à la place. – Jester

+0

Utilisez le débogueur pour exécuter le code et voir où il ne fait pas ce que vous voulez. – Jester

Répondre

1

Vous avez une bonne structure dans les lieux.

Cependant, dans un certain nombre d'endroits, les commentaires ne correspondent pas au code (par exemple, vous faites un tas de couper-n-coller). Et, bien que je me rende compte que vous débutez, beaucoup de vos commentaires sur la barre latérale régurgitent l'instruction asm. (Par exemple):

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

Il vous aidera dans votre compréhension si les commentaires ont suivi l'algorithme:

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

Une autre question est que checkloop: devrait contenir en fait une boucle plutôt que d'un nombre fixe de bne insts . Mis à part certains des problèmes mentionnés par d'autres dans le bloc de commentaire supérieur, un grand est que vous êtes en train de réinitialiser le pointeur phrase/chaîne. Ce dont vous avez vraiment besoin, c'est d'un autre pointeur [incrémenté par un] qui se souvient de "où vous vous étiez arrêté" dans la phrase et redémarre la boucle interne de celui-ci (checkloop:)

Bien que j'ai essayé de conserver autant de votre code que je pourrait, j'ai dû refactoriser un peu. Un "astuce" que j'ai utilisé était de créer une fonction qui invite l'utilisateur, lit dans le tampon, puis convertit les périodes et les retours à la ligne en espaces [ceci rend la boucle de numérisation beaucoup plus facile]

De toute façon, le voici [s'il vous plaît pardon le nettoyage de style gratuit]:

.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