Сортировка массива в MIPS с указателем стека

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

Также я должен использовать указатель стека.

это код С++ для него:

for (i=0; i<n; i+=1) {
    for (j=i-1; j>=0 && v[j] > v[j+1]; j-=1) {
    swap (v,j);
    }
}

это код. Я пробовал использовать jal и jr и все испортил.

.data
.align 2
ARRAY: .word 12, 4, 23, 2, 5, 26, 13, 42, 41, 18
msg1: .asciiz " "

.text
.globl main
main:
la $a0, ARRAY
addi $a1, $zero, 10     #array length

sort:
addi $sp, $sp, -20
sw $ra, 16($sp)
sw $s3, 12($sp)
sw $s2, 8($sp)
sw $s1, 4($sp)
sw $s0, 0($sp)

add $s0, $zero, $zero
add $s2, $a0, $zero
add $s3, $a1, $zero

loop1:
slt $t0, $s0, $s3
beq $t0, $zero, exit1
addi $s1, $s0, -1

loop2:
slt $t0, $s1, $zero
bne $t0, $zero, exit2
sll $t1, $s1, 2
add $t2, $s2, $t1
lw $t3, 0($t2)
lw $t4, 4($t2)
slt $t0, $t4, $t3
beq $t0, $zero, exit2

add $a0, $s2, $zero
add $a1, $s3, $zero

swap:
?

addi $s1, $s1, -1
j loop2

exit2:
addi $s0, $s0, 1
j loop1

exit1:
lw $s0, 0($sp)
lw $s1, 4($sp)
lw $s2, 8($sp)
lw $s3, 12($sp)
lw $ra, 16($sp)
addi $sp, $sp, 20

exit:
li $v0, 10
syscall

что мне нужно сделать, чтобы поменять меньший на больший, чтобы я мог отсортировать массив?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
816
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не должны реализовывать циклы, как вы это делаете, с проверкой на входе в цикл. Вам нужна дополнительная ветвь, которая менее эффективна и затрудняет понимание кода.

Если у вас есть петля

for(initial; test; increment) { body }

Просто переведите это на:

   initial
loop:
   body
   increment
   test -> loop

Вам нужна только уникальная ветвь, и это значительно улучшает читаемость кода.

Кроме того, начните с написания кода C с указателями, чтобы упростить перевод.

for (i=0; i<n; i+=1) {
    for (j=i-1, parray=array[i-1]; j>=0 ; j-=1, parray--) {
       if (*parray > *(parray+1)) 
         swap (parray); // the pointer is sufficient
    }
}

Что касается операции подкачки, зачем вам подпрограмма? Вы сохранили значения массива [j] и массива [j+1] в регистрах, и вам просто нужно записать их обратно на свои места.

Вот возможный перевод (пропуская начало и конец, которые остаются неизменными)

...
sort:
addi $sp, $sp, -20
sw $ra, 16($sp)
sw $s3, 12($sp)
sw $s2, 8($sp)
sw $s1, 4($sp)
sw $s0, 0($sp)

   add $s0, $zero, $zero # i=0
   add $s2, $a0, $zero   # @array
   add $s3, $a1, $zero   # N

loop1:
    addi $s1, $s0, -1    # j=i-1
    sll $t1, $s1, 2
    add $t2, $s2, $t1    # @array[j]

loop2:
    lw $t3, 0($t2)         # $t3 array[j]
    lw $t4, 4($t2)         # $t4 array[j+1]
    sgt $t0, $t3, $t4      # array[j] > array[j+1]?
    bne $t0, $zero, noswap # no? -> noswap

swap:
    # just exchange the loaded values of array[j] and array[j+1]
    sw $t3, 4($t2)
    sw $t4, 0($t2)

noswap:

    addi $s1, $s1, -1   # j--
    addi $t2, $t2, -4   # array--
    sge $t0, $s1, $zero # j>=0?
    bne $t0, $zero, loop2

    addi $s0, $s0, 1  #i++
    slt $t0, $s0, $s3 #i<N?
    bne $t0, $zero, loop1

exit1:
...

Количество загрузок может быть уменьшено, так как в каждой итерации у вас уже есть уже загруженный массив[i].

Другие вопросы по теме