Возникло исключение при попытке отобразить длину строки, заданной пользователем. MIPS

Я пытаюсь вычислить длину строки, заданной пользователем. Каждый раз, когда я пытаюсь запустить код, я получаю сообщение «Произошло исключение на ПК = (определенный адрес), за которым следует сообщение: «Неверный адрес в данных/чтении стека: (другой адрес). Я знаю, что это как-то связано со стеком, но я не могу понять проблему. Код в MIPS прекрасен, и я использую QtSpim. Ваша помощь будет очень признательна.

sentence:   .space 6
Prompt: .asciiz "Enter the sentence. Max 6 characters, plus a terminator  .\n"  

        .text       # Start of code section
main:               # The prompt is displayed.

    li $v0, 4        # system call code for printing string = 4
    la $a0, Prompt  # load address of string to be printed into $a0
    syscall         # call operating system to perform operation;
                    # $v0 specifies the system function called;
                    # syscall takes $v0 (and opt arguments)

##read the string, plus a terminator, into the sentence
    la      $t0,    sentence
    li      $t0,    6
    li      $v0,    8

    add $v0, $zero, $zero   #initialize length to zero
loop:
    lbu $s0, 0($t0)      #load one character of string
    addi $t0,$t0,1          #point to next character
    addi $v0,$v0,1          #increment length by 1
    bne $s0,$zero, loop     #repeat if not null yet
end_loop:
    addi $v0, $v0, -1       #don't count the null terminator

    li $v0, 4               #display the actual length
    syscall

exit: #exit the program 
    li $v0, 10
    syscall

person T4000    schedule 25.04.2013    source источник


Ответы (1)


##read the string, plus a terminator, into the sentence
    la      $t0,    sentence
    li      $t0,    6

Здесь вы загружаете адрес sentence в $t0, а затем сразу перезаписываете $t0 значением 6. Это, вероятно, основная причина исключения, поскольку следующий lbu попытается прочитать с адреса 0x00000006. Я предлагаю вам удалить файл li.

   li      $v0,    8

    add $v0, $zero, $zero   #initialize length to zero

Этот li не имеет смысла, так как вы устанавливаете $v0 на ноль в самой следующей строке, поэтому этот li также можно удалить.

sentence:           .space 6
Prompt:     .asciiz "Enter the sentence. Max 6 characters, plus a terminator  .\n" 

Вы говорите, что пользователю разрешено вводить до 6 символов. Но вы выделяете место только для 6 байтов, а это означает, что терминатор NULL не подходит, если пользователь фактически вводит 6 символов.

person Michael    schedule 25.04.2013
comment
когда я пытаюсь избавиться от: li $t0, 6, он дважды отображает подсказку. Но когда я сохраняю эту строку, подсказка отображается только один раз. Однако у меня все еще нет ожидаемого результата при попытке удалить две строки. - person T4000; 25.04.2013
comment
@ T4000: Этого следовало ожидать, поскольку вы заканчиваете свой код повторным выполнением системного вызова 4 (print_string), а $a0 все еще указывает на Prompt. У вас также нет кода, который фактически читает строку от пользователя. - person Michael; 25.04.2013