Функция обмена MIPS

Как видно из сегодняшней истории вопросов, я работаю над проектом MIPS, который перевернет строку, в данном случае «Hello, World». Я думаю, что у меня есть мои функции разворота цикла и строки, но я не могу понять саму функцию подкачки или как вывести управляемую строку.

Я знаю, что основной своп для чего-то вроде этого будет:

sll $t1, $a1, 2
add $t1, $a0,$t1
lb $t0,0($t1)
lb $t2, 4($t1)

sb $t0,0($t1)
sb $t2, 4($t1)
jr $ra

Но я понятия не имею, что это делает или как я интерпретирую это, чтобы соответствовать моему коду. Если бы какой-нибудь святой мог объяснить, как это работает и как работают системные вызовы, я был бы бесконечно благодарен. Мой код ниже:

.data 

    string: .asciiz "Hello, World!"

.text
main:
    li $v0, 4
    la $a0, string #store string in a0
    syscall



    jal stringreverse

stringreverse:
    add $t0,$a0,$zero   #base address of string
    add $a1, $zero,14   #stores size of string in a1
    addi $t2, $a1, -1   #j = length -1
    add $t3,$zero,$zero     #i = 0

loop:
    jal swap
    addi $t2,$t2,-1     #j--
    addi $t3,$t3,+1     #i++

    slt  $t7,$t3,$t2 #set t7 to 1 when j is less than i
    bne  $t7,$zero,loop # if i is greater than j, keep looping
    j done
swap:   #swaps the sooner element with the later and returns back to the loop
    lb      $v0,0($t3)              # updated to fit my registers t3 =i
    lb      $v1,0($t2)              # updated to fit my registers t2 =j

    sb      $v1,0($t3)              
    sb      $v0,0($t2)              

    jr $ra

done:
    .....procedure here.....
    syscall 

person djjeane    schedule 21.03.2018    source источник
comment
См. Мой ответ на ваш предыдущий вопрос: stackoverflow.com/questions/49393986/ Кстати, вам действительно стоит просто отредактировать оригинал, а не публиковать [слегка измененный] дубликат   -  person Craig Estey    schedule 21.03.2018
comment
Реверс по структуре похож на мой. В моем обратном / свопинге я использую char* указатели повсюду (вместо индексных переменных). Обратите внимание, что main -> reverse -> swap, поэтому значение $ra из main должно быть сохранено reverse, потому что jal swap его затирает.   -  person Craig Estey    schedule 21.03.2018
comment
Также обратите внимание, что из Mips ABI, только $s0-$s7 должен быть сохранен (и регистр стека должен при выходе из функции указывать на то же место, где он был записью функции). В противном случае любой рег можно использовать для любых целей. Я намеренно выбрал из колеи использование $v0/$v1 в моем swap (против $t*). Единственные действительно зашитые [архитектурой] регистры - это $ra и $zero   -  person Craig Estey    schedule 21.03.2018
comment
Ценю совет, этикета не знала. Что касается вашего второго комментария, не могли бы вы уточнить? Я работаю с примерами и не очень разбираюсь в том, как работают эти процедуры. Так что я не совсем понимаю, что вы имеете в виду, говоря о значении $ ra.   -  person djjeane    schedule 21.03.2018
comment
Когда вы выполняете jal func, он помещает адрес возврата (адрес после jal в регистр $ra (адрес возврата)), а затем переходит к func. Использование $ra от jal - один из немногих вариантов, которые можно использовать заранее. Обычный способ возврата - jr $ra, что означает переход к адресу в $ra. Это обычная последовательность, но jr не привязан к $ra, вы можете использовать любой другой регистр (например, в моем коде я использовал $t0, чтобы проиллюстрировать это: jr $t0, потому что раньше я сохранил $ra в $t0)   -  person Craig Estey    schedule 21.03.2018
comment
Хорошо, это было просто предупреждение. Понял! Я только что запустил код, отредактированную версию с вашим аргументом подкачки, который я показываю выше, и получаю ошибку времени выполнения, вероятно, из-за того, что не удалось перевести ваши регистры в мои.   -  person djjeane    schedule 21.03.2018
comment
строка 31: исключение времени выполнения в 0x0040003c: адрес вне диапазона 0x00000000 Это первая строка моего свопа, поэтому я просто предполагаю, что мое значение i, или LHS, отключено. Любые идеи? Что-то очевидное? Кроме того, спасибо, что держали меня за руку   -  person djjeane    schedule 21.03.2018
comment
Ваши $t2/$t3 являются индексами, а не указателями, поэтому lb будет ошибкой (например, $t3 имеет ноль в начале). lb $v0,0($t3) похож на char v0 = *t3. lb $v0,5($t3) будет похоже на char v0 = *(t3 + 5). Итак, ваше обратное действие [на C]: swap(i,j) вместо swap(&array[i],&array[j]) Я обновил свой ответ на другой вашей странице, чтобы помочь   -  person Craig Estey    schedule 21.03.2018


Ответы (1)


Похоже, вы обрабатываете lb (инструкция загрузки байта) как a la (инструкция адреса загрузки).

Вероятно, вы захотите сделать что-то еще вроде этого:

swap:
    lb    $temp1,   str($t2)    #load temp1 address with byte at $t2 in str 
    lb    $temp2,   str($t1)    #load temp2 address with byte at $t1 in str
    sb    $temp2,   str($t2)    #store temp2 byte into $t2'th position in str
    sb    $temp1,   str($t1)    #store temp1 byte into $t1'th position in str
    jr    $ra

с некоторыми данными, например:

.data
str:
    .asciiz "your string here"

Надеюсь, это немного проясняет вам ситуацию.

person eunique    schedule 21.03.2018
comment
Я считаю, что регистры $ a # и $ v # обычно зарезервированы для использования в качестве аргументов для системных вызовов. В этом случае соответствующие системные вызовы, которые вы ищете, - это li $v0, 4 #system call to print la $a0, ($regwithstringaddress) #load string syscall и li $v0, 10 #system call to exit syscall - person eunique; 21.03.2018
comment
Огромный привет, мой мужчина! Итак, моя первая ли, с которой я начал основное, все время была неправильной? Я должен быть на li $ v0, 8 la $ a0, строковом системном вызове, чтобы читать в строке? - person djjeane; 21.03.2018
comment
Да, код в моем предыдущем комментарии должен загрузить $ a0 со строкой, а затем распечатать ее. - person eunique; 21.03.2018