String 在MIPS中查找给定字符串中的元音数

String 在MIPS中查找给定字符串中的元音数,string,mips,qtspim,String,Mips,Qtspim,我必须编写一个程序来计算MIPS中字符串中的元音数。我当前的代码在QtSPim中给了我一个内存越界错误。 我在MIPS的初学者水平,所以任何帮助将不胜感激。 迄今为止的代码: .data str: .space 20 my_chars: .space 20 vow1: .byte 'a' vow2: .byte 'e' vow3: .byte 'i' vow4: .byte 'o' vow5: .byte 'u' .text main: li $s0,0

我必须编写一个程序来计算MIPS中字符串中的元音数。我当前的代码在QtSPim中给了我一个内存越界错误。 我在MIPS的初学者水平,所以任何帮助将不胜感激。 迄今为止的代码:

    .data
  str: .space 20
 my_chars: .space 20
vow1: .byte 'a'
vow2: .byte 'e'
vow3: .byte 'i'
vow4: .byte 'o'
vow5: .byte 'u'
.text
main:
li $s0,0                    #initilaze loop var1
li $t0,20                    #initialize loop var2
li $s1,0                    #initialize counter
la $t1, my_chars              # base address of array
li $a1,20                     #max input to be read
li $a0,8
syscall
loop:
 beq $s0, $t0, exit
la $t2, str                  #string into t2
lb $v0, 0($t2)                 #access first index
lb $t9, vow1
beq $v0, $t9, then             #comparing to a
then:
addi $s1, $s1, 1

lb $t8, vow2
beq $v0, $t8, then1             #comparing to e
then1:
addi $s1, $s1, 1
lb $t7, vow3
beq $v0, $t7, then2             #comparing to i
then2:
addi $s1, $s1, 1
lb $t6, vow4
beq $v0, $t6, then3             #comparing to o
then3:
addi $s1, $s1, 1
lb $t5, vow5
beq $v0, $t5, then4             #comparing to u
then4:
addi $s1, $s1, 1

addi $t1, $t1,1               #increment base address
addi $s0, $s0,1               #increment loop variable
 j L1
 syscall

因为您发布的代码缺少标签等。我无法运行它来查找运行时错误

从外观检查来看,从用户输入代码读取有一些问题
li$a0,8
应该是
li$v0,8
[读取字符串的系统调用号]<代码>$a0应包含要读入的缓冲区地址。在您的代码中,这是
8
,并且[可能]不是有效地址。因此,您可能需要类似于
la$a0,my_chars
la$a0,str
的内容。其中一个应该是输入缓冲区,另一个似乎不必要

当我尝试添加标签(基于有根据的猜测)时,我意识到如果元音在一个数组中,你的程序可能会简单得多,所以我重构了代码

我还更改了循环终止以查找EOS(0x00),而不是减少计数,这可能是另一个越界问题的潜在来源。这也减少了所需的寄存器数量(即降低了复杂性)

我添加了缺少的样板文件/系统调用[请原谅这种无缘无故的风格清理]:

    .data
vowel:      .asciiz     "aeiou"
msg_prompt: .asciiz     "Enter string: "
msg_out:    .asciiz     "Number of vowels is: "
msg_nl:     .asciiz     "\n"
str:        .space      80

    .text
    .globl  main
main:
    # print user prompt
    li      $v0,4
    la      $a0,msg_prompt
    syscall

    # get string to scan
    li      $v0,8
    la      $a0,str
    li      $a1,80
    syscall

    li      $s2,0                   # initialize vowel count
    la      $s0,str                 # point to string

# registers:
#   s0 -- pointer to string character
#   s1 -- pointer to vowel character
#   s2 -- count of vowels
#
#   t0 -- current string character
#   t1 -- current vowel character
string_loop:
    lb      $t0,0($s0)              # get string char
    addiu   $s0,$s0,1               # point to next string char
    beqz    $t0,string_done         # at end of string? if yes, fly

    la      $s1,vowel               # point to vowels

vowel_loop:
    lb      $t1,0($s1)              # get the vowel we wish to test for
    beqz    $t1,string_loop         # any more vowels? if not, fly
    addiu   $s1,$s1,1               # point to next vowel
    bne     $t0,$t1,vowel_loop      # is string char a vowel? -- if no, loop
    addi    $s2,$s2,1               # yes, increment vowel count
    j       string_loop             # do next string char

string_done:
    # print count message
    li      $v0,4
    la      $a0,msg_out
    syscall

    # print vowel count
    li      $v0,1
    move    $a0,$s2
    syscall

    # print a newline
    li      $v0,4
    la      $a0,msg_nl
    syscall

    # exit program
    li      $v0,10
    syscall

您的问题至少应包括确切的错误消息和错误所指的代码行。它显示内存超出范围消息,而不是我所说的其他消息。您应发布准确、完整的消息,并指出错误消息所指的代码行。确切消息:突出显示的“内存地址超出边界”行:[004000b4]0000000 c syscall;50:syscallWell,在您发布的代码末尾有一条错误的
syscall
指令。这应该做什么?它前面的行是无条件跳转到代码中不存在的某个标签
L1