Простая сборка MIPS - PullRequest
       0

Простая сборка MIPS

1 голос
/ 01 апреля 2012

Я не могу понять, что я делаю неправильно в моем ассемблерном коде.Я пытаюсь написать программу, которая сравнивает две строки с нулевым символом в конце, которые вводятся как $ a0, и $ a1 иногда в разделе «main:», а затем вызывает

jal hamming

, чтобы запустить программу.

В основном для этого раздела я хочу, чтобы две строки сравнивались char по char, пока одна строка не достигнет нулевого завершающего char.Затем программа останавливается и возвращает количество символов, отличных до завершения.

Я думаю, что это связано с прыжками, которые я использую, но я не совсем уверен.Программа довольно длинная, поэтому я взял основную часть, которая, на мой взгляд, является проблемой (поэтому игнорирую такие переменные, как $ a3, которые уже были инициализированы и определены):

diffchar:
        li $t4, 0
        li $t5, 1

        beq $a0, $a1, samechars
        move $v0, $t5
        j diffcharend

samechars:
        move $v0, $t4

diffcharend:
        jr $ra

hamming:

absvaluedone:
        li $a2, 0
        #li $v0, 0

        move $t0, $a0
        move $t1, $a1

hammingloopbegin:
        lb $t2, 0($t0)
        lb $t3, 0($t1)
        beq $t2, $0, hammingdone
        beq $t3, $0, hammingdone

        la $a0, 0($t0)
        la $a1, 0($t1)
        jal diffchar **#this is the line that causes me problems, if I take this out it is fine**
        beq $v0, $0, next
        addiu $a2, $a2, 1

next:
        addiu $t0, $t0, 1
        addiu $t1, $t1, 1
        j hammingloopbegin

hammingdone:
        add $v0, $a2, $a3
        jr $ra

Когда я запускаю свою программу,вывод выглядит как бесконечный цикл, который постоянно говорит:

Exception occurred at PC=0x00400144
  Bad address in data/stack read: 0x10021226
  Exception 7  [Bad address in data/stack read]  occurred and ignored
Exception occurred at PC=0x00400140
  Bad address in data/stack read: 0x1002121b
  Exception 7  [Bad address in data/stack read]  occurred and ignored

Я думаю, что-то не так с diffchar или процессом, который я использую для перехода к diffchar.Я впервые пишу ассемблерный код, так что я думаю, что есть кое-что действительно простое, что мне не хватает, что создает этот беспорядок.Любые указатели были бы великолепны.

Спасибо за помощь

1 Ответ

2 голосов
/ 01 апреля 2012

Вы не сохраняете обратный адрес до jal diffchar. Возвращается и $ra все еще содержит новое значение. Когда вы снова jr $ra наберете hammingdone, вы вернетесь назад сразу после вызова diffchar. Вам нужно сохранить $ra где-то перед вызовом diffchar и восстановить его после возврата вызова.

Вот хорошее объяснение вложенных процедур в MIPS , которое описывает проблему, с которой вы столкнулись, и решение, использующее стек времени выполнения:

При выполнении инструкции jal B адрес возврата в регистре $ra для процедуры A будет заменен обратным адресом для процедура B. Процедура B вернётся правильно к A, но когда процедура A выполняет инструкцию jr, она снова вернется к адрес возврата для B, который является следующей инструкцией после jal B in процедура A. Это помещает процедуру A в бесконечный цикл.

...

Системный стек обычно используется для сохранения адресов возврата. Они могут будет помещен в стек при вызове процедуры и передан выполнить инструкцию возврата.

Адрес возврата в регистре $ra может быть помещен в системный стек со следующим кодом MAL:

    sw      $ra, ($sp)
    add     $sp, -4

Следующий код извлекает адрес возврата из верхней части стека и возвращает его в регистр $ra:

    add     $sp, 4
    lw      $ra, ($sp)
...