2

I have to write a program to count the number of vowels in a string in MIPS. My current code is giving me a memory out of bounds error in QtSPim. I'm at the beginner level in MIPS, so any help would be appreciated. Code so far:

    .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
Emaan Hasan
  • 21
  • 1
  • 2
  • Your question should at the minimum include the exact error message, and the line of code the error refers to. – Michael Jan 31 '17 at 18:35
  • It presents a memory out of bounds message, no other message that I can see – Emaan Hasan Jan 31 '17 at 18:54
  • Like I said, you should post the **exact**, **complete** message, and point out the line of code that the error message refers to. – Michael Jan 31 '17 at 19:04
  • Exact message: "Memory address out of bounds" line highlighted: [004000b4] 0000000c syscall ; 50: syscall – Emaan Hasan Jan 31 '17 at 19:16
  • Well, there's a stray `syscall` instruction at the end of the code you've posted. What's that supposed to do? The line preceeding it is an unconditional jump to some label `L1` that doesn't exist in your code. – Michael Jan 31 '17 at 20:42

1 Answers1

1

Because your posted code had missing labels, etc. I couldn't run it to look for the runtime error.

From visual inspection, the read from user input code had a few issues. li $a0,8 should be li $v0,8 [the syscall number to read a string]. $a0 should contain the address of the buffer to read into. In your code, this was 8 and [probably] not a valid address. So, you'd probably want something like la $a0,my_chars or la $a0,str. One of them should be the input buffer and the other seems unnecessary.

As I was trying to add labels [based on educated guesswork], I realized that your program could/would be much simpler if the vowels were in an array, so I refactored the code.

I also changed the loop termination to look for EOS (0x00) instead of decrementing a count, which may have been another potential source of an out-of-bounds issue. This also reduces the number of registers needed (i.e. reduces complexity)

I added the missing boilerplate/syscalls [please pardon the gratuitous style cleanup]:

    .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
Craig Estey
  • 30,627
  • 4
  • 24
  • 48