Код сборки MIPS для подсчета количества цифр в строке

Я пишу код сборки MIPS для подсчета количества цифр в строке. Например, если пользовательская строка была: «qapww9 ... $$$ 64», на выходе будет 3.

Я использовал коды ascii, чтобы установить границу целых чисел (48 для 0, 57 для 9). Я хотел проверить каждый символ, если он больше или равен 0, затем меньше или равен 9, если да, то добавьте один в счетчик, а затем перейдите к следующему символу. Мой код не работает после ввода строкового ввода

РЕДАКТИРОВАТЬ: я получаю отзыв о том, что я неправильно увеличиваю каждый символ строки. В настоящее время я делаю addi $t0, $t0, 1.

# MIPS assembly language program to count the number of decimal digits in an ascii string of characters.
# $a0 = $t0 = user input
# $t1 = counter
# $t2 = temporary register to hold each byte value
.data
    length: .space 100
    p: .asciiz "\nEnter a string: "
    p2: .asciiz "\nNumber of integers: "
.text

#Prompt User for String
   la $a0, p                   #print prompt
   li $v0, 4                #load string stored in v0
   syscall                  #display prompt string

#Get user input
   li $v0, 8                #load string stored in v0
   la $a0, length              #set string length to 100
   addi $a1, $0, 100           #add length 100 to regist $a1
   syscall

   move $t0, $a0                #user input is now in register $t0
   addi $t1, $0, 0              #initialize counter

#loop to check if greater or equal to 0
lowerBound:
   lb $t2, 0($t0)           #load first character of user input into $t2
   bge $t2, 48, upperBound     #branch to upperBound checker if char is greater than or equal 0
   addi $t0, $t0, 1         #increment to next character in string
   beqz $t0, end            #if character = 0 (end of string), end
   j lowerBound

#loop to check if less than or equal to 9
upperBound:
    ble  $t2, 57, count_digits  #if in the range 0-9, just to count digits and add 1 to counter
    j lowerBound            #loop through again

count_digits:
    addi $t1, $t1, 1           #add 1 to counter
    j lowerBound

end:
    li $v0, 4          #load string print service
    la $a0, p2         #load address of prompt 2 inro $a0
    syscall            #print prompt
    la $a0, ($t1)          #load address of count into $a0
    li $v0, 1          #specify print integer service
    syscall            #print count

person Ooka    schedule 25.02.2020    source источник
comment
Вы загружаете одного и того же персонажа снова и снова. Ваш счетчик не $t2, и как именно вы собираетесь добраться до end?   -  person Jester    schedule 26.02.2020
comment
@ Шут, как так? Где я ошибаюсь, когда не увеличиваю каждый символ в проверяемой строке. Я планирую закончить, используя строку: beqz $ t2, end ... Я считаю, что это означает, что если символ $ t2 = 0, то это означает, что строка пуста, поэтому я закончил проверку.   -  person Ooka    schedule 26.02.2020
comment
lb $t2, 0($t0) загружается из $t0 и $t0 никогда не меняется. Также, если символ меньше 48, вы просто продолжаете цикл в блоке lowerBound, вы никогда не выходите.   -  person Jester    schedule 26.02.2020
comment
addi $t2, $t2, 1 разве это не переходит к следующему символу? Затем он снова проходит через lowerBound, чтобы проверить следующий?   -  person Ooka    schedule 26.02.2020
comment
Почему увеличение $t2 может сделать что-нибудь полезное?   -  person Jester    schedule 26.02.2020
comment
@Jester, насколько мне известно, lb $t2 0($t0) первый символ пользовательской строки теперь находится в $t2, тогда я могу проверить, находится ли он между 0-9, используя мои инструкции ветвления. после выполнения этих инструкций я мог бы сделать addi $t2, $t2, 1, что означает переход к следующему символу для проверки. Я добавляю 1 к счетчику каждый раз, когда символ находится в диапазоне от 0 до 9. Я буду делать это до тех пор, пока строка не станет пустой (думаю, это будет beqz $t2, end). Тогда я мог бы напечатать номер счетчика. Как еще я мог бы проверить каждый символ, если бы я не увеличивал $t2?   -  person Ooka    schedule 26.02.2020
comment
$t2 - это загруженный вами символ. Увеличивать его бессмысленно. Вы хотите увеличить $t0, чтобы использовать это для загрузки следующего символа в $t2.   -  person Jester    schedule 26.02.2020
comment
Хорошо, ive изменил его так, чтобы $t0 увеличивался вместо $t2, однако возникает та же проблема.   -  person Ooka    schedule 26.02.2020
comment
beqz должен по-прежнему ссылаться на $t2, потому что вы хотите проверить, был ли символ нулем. Также переходы продолжения от upperBound и count_digits должны возвращаться к приращению, иначе эти случаи не перейдут к следующему символу. PS: научитесь использовать симулятор для пошагового выполнения кода, чтобы увидеть, что он делает.   -  person Jester    schedule 26.02.2020


Ответы (1)


Вы застряли в бесконечном цикле, когда символ ASCII больше 57. Потому что в этом случае вы перейдете к upperBound, где вы бесконечно вернетесь к lowerBound, поскольку указатель на строку ($ t0) в этом случае не будет увеличиваться. Просто переместите часть приращения над bge, чтобы она выполнялась всегда.

Также вы пытаетесь напечатать адрес счетчика по неизвестной причине, а не то значение, которое вам нужно.

Модифицированный код

# MIPS assembly language program to count the number of decimal digits in an ascii string of characters.
# $a0 = $t0 = user input
# $t1 = counter
# $t2 = temporary register to hold each byte value
.data
    length: .space 100
    p: .asciiz "\nEnter a string: "
    p2: .asciiz "\nNumber of integers: "
.text

#Prompt User for String
   la $a0, p                   #print prompt
   li $v0, 4                #load string stored in v0
   syscall                  #display prompt string

#Get user input
   li $v0, 8                #load string stored in v0
   la $a0, length              #set string length to 100
   addi $a1, $0, 100           #add length 100 to regist $a1
   syscall

   move $t0, $a0                #user input is now in register $t0
   addi $t1, $0, 0              #initialize counter

#loop to check if greater or equal to 0
lowerBound:
   lb $t2, 0($t0)           #load first character of user input into $t2
   addi $t0, $t0, 1         #increment to next character in string
   bge $t2, 48, upperBound     #branch to upperBound checker if char is greater than or equal 0
   beqz $t2, end            #if character = 0 (end of string), end
   j lowerBound

#loop to check if less than or equal to 9
upperBound:
    ble  $t2, 57, count_digits  #if in the range 0-9, just to count digits and add 1 to counter
    j lowerBound            #loop through again

count_digits:
    addi $t1, $t1, 1           #add 1 to counter
    j lowerBound

end:
    li $v0, 4          #load string print service
    la $a0, p2         #load address of prompt 2 inro $a0
    syscall            #print prompt
    move $a0, $t1          #load count into $a0
    li $v0, 1          #specify print integer service
    syscall            #print count
person Eraklon    schedule 28.02.2020