MIPS: печать количества гласных и согласных в строке

У меня работает программа, моя единственная проблема заключается в том, что цикл выполняется на один раз больше, чем должен, что увеличивает количество согласных слишком много раз. Я, конечно, могу обойти это, просто вычитая 1 из счета в конце, но мне любопытно, почему он работает дополнительное время. Я использовал пошаговую функцию, чтобы попытаться устранить неполадки в PCSpim, и я вижу, что $a0 = 0000000a вместо 00000000 в том, что должно быть последним циклом. Почему это происходит?

#################################################
#                       #
#               text segment            #
#                       #
#################################################

    .text
    .globl __start
__start:                # execution starts here

    la $a0,prompt1  # print prompt on terminal
    li $v0,4        # system call to print
    syscall         # out a string

    la $a0,string
    li $a1,20
    li $v0, 8   # syscall 8 reads string/letter
    syscall
    
    li $t1, 0   # register used to keep track of number of vowels
    li $t2, 0   # register used to keep track of number of consonances

    la $a1, string  # prepare for passing a letter to the procedure
    

loop:   
    lb $a0, 0($a1)  # load one character from the string
    beqz $a0, End   # if no more characters then go to End
    addi $a1,$a1,1  # increment address position to print next character in string

    jal vowelp  # procedure call

    move $t0,$v0    # save the value returned from the procedure call

    beqz $t0, NotVowel
    
    addi $t1, $t1, 1

    j loop

NotVowel:
    addi $t2, $t2, 1
    
    j loop
End:    
    la $a0, answer1
    li $v0, 4
    syscall
    
    move $a0, $t1
    li $v0, 1
    syscall     # print number of vowels

    la $a0,endl # syscall to print out
    li $v0,4    # a new line
    syscall     

    la $a0, answer2
    li $v0, 4
    syscall
    
    addi $t2, $t2, -1   

    move $a0, $t2
    li $v0, 1
    syscall     # print number of consonants

    la $a0,endl # syscall to print out
    li $v0,4    # a new line
    syscall 

    li $v0,10
    syscall     # Bye!

##############################################################
## Define the procedure vowelp
##############################################################

vowelp:

    li $v0, 0   # initialize $v0 to 0
    beq $a0,' ',loop
    beq $a0,'A',yes 
    beq $a0,'a',yes
    beq $a0,'E',yes
    beq $a0,'e',yes
    beq $a0,'I',yes
    beq $a0,'i',yes
    beq $a0,'O',yes
    beq $a0,'o',yes
    beq $a0,'U',yes
    beq $a0,'u',yes
    jr $ra
yes:    li $v0,1
    jr $ra
    

#################################################
#                       #
#               data segment            #
#                       #
#################################################

        .data
    string:     .space 20
    prompt1:    .asciiz "Enter a string: "
    
    answer1:    .asciiz "The number of vowels in the string is: \n"
    answer2:    .asciiz "The number of consonants is: \n"
    message:    .asciiz "The character entered is not a vowel."
    ans1:       .asciiz "The character entered is a vowel. "
    endl:       .asciiz "\n"       

##

person Nicholas Kelly    schedule 03.04.2021    source источник
comment
Кстати, есть трюк, чтобы сделать это гораздо более эффективным: проверить, является ли символ буквенным, и превратить его в индекс в алфавите (ori / addiu -'a' / branch) (Проверка того, находится ли значение в одном из двух диапазонов), а затем используйте этот индекс в алфавите для таблицы поиска. Или вместо таблицы памяти целочисленное растровое изображение в регистре, которое вы индексируете с помощью srl $v0, $t1, $t0/andi $v0, $v0, 1, чтобы получить индексированный бит, затем add $t1, $t1, $v0, чтобы добавить 0 или 1 к вашему счетчику. (Добавление 0 не является операцией, вам не нужно ветвление, чтобы избежать этого.)   -  person Peter Cordes    schedule 03.04.2021
comment
Что здесь делает компилятор, который позволяет выполнять сравнение многих значений с несколькими фактическими сравнениями? содержит более подробную информацию об идее использования целое число в регистре в виде растрового изображения. (С x86 asm, но с той же разницей.) Вызов оценки пользователей №1: Деннис ♦ В ответе codegolf используется растровое изображение согласных: инвертируйте это, и у вас есть растровое изображение гласных (например, ~0x3efbeee). Или просто считать согласные и буквы алфавита, и делать гласные = буквы - согласные в конце, чтобы правильно отклонить пробел, новую строку и т.д.   -  person Peter Cordes    schedule 03.04.2021
comment
(Ваш способ не неправильный, я просто указываю более эффективный способ, который может быть интересно понять.)   -  person Peter Cordes    schedule 03.04.2021