2013-07-22 2 views
2

Я знаю, что есть аналогичный вопрос here. Я хотел бы думать об этом как о продолжении этого вопроса, но более подробно.Перемещение элементов в массиве в сборке MIPS? (более ясный)

Вот соответствующие фрагменты кода C, который я хочу перевести на MIPS:

int a = [100]; 
... 
j = 0; 
while (j<50){ 
    if (a[j] > a[99-j]) { 
     tmp = a[99-j]; 
     a[99-j] = a[j]; 
     a[j] = tmp; 
    } 
    j = j+1; 
} 

(Так что это в основном работает как реверсе)

До сих пор я сделал в MIPS:

.data 
array: .word 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 
    79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 
    59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 
    39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 
    19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,0 
    .text 
    .globl main 
main: 
    la $s1, array # $s1 = array address 
    la $s3, array 
    li $s0, 0  # j = 0 
    lw $t0, 0($s1) # $t0 = a[0] 
    lw $t1, 396($s3) # $t1 = a[99] 

while: beq $s0, 50, end # break from while loop once j = 50 

if: blt $t0, $t1, iterj # if the if statement not satisfied, branch to iterj 
    sw $t1, 0($s1) # write to a[99-j] 
    sw $t0, 396($s1) # write to a[j] 

iterj: addi $s0, $s0, 1 # increment j 
    addi $s1, $s1, 4 # increment source address starting with j = 0 
    addi $s3, $s3, -4 # decrement source address starting with j = 99 
    lw $t0, 0($s1) 
    lw $t1, 396($s3) 
    j while 
end: 

Резюме из того, что я сделал в MIPS:

В принципе, я попытался инициализировать массив в $ s1 и попытался изо всех сил сделать свопы на нем. Затем я понял, что мне также нужно увеличить адрес источника в [0] и в то же время уменьшить адрес источника в [99]. Так я думал, что я не могу использовать только один массив, который я тогда сделал идентичный массив в $ s3, чтобы справиться с этим:

addi $s1, $s1, 4 # increment source address starting with j = 0 
addi $s3, $s3, -4 # decrement source address starting with j = 99 

Сейчас часть мне нужна помощь:

код работает (правильно меняются) последовательно от 0 до 31 (все в шестнадцатеричной форме, показанные в MARS), затем 31 к 1, а затем от 63 до 47. Очевидно, что я делаю неправильно. Все, что мне нужно, это вернуть 0-63 (в шестнадцатеричном формате) или от 0 до 99 (в делении) путем обмена. Любые намеки?

ответ

2

Ну, вы ошибаетесь в требовании двух массивов, однако вы пришли к такому выводу. Помните, что все, что может быть написано на C, может быть написано на сборке, поэтому код C, который вы предоставили, должен служить моделью.

--- EDIT

То, что я хотел бы предложить первым, это загрузить адрес массива и вычислить конечный адрес.

la $t0 array 
addi $t1 $t0 396 #last element of array 

Тогда в теле цикла:

lw $t2 0($t0) 
lw $t3 0($t1) 
sw $t2 0($t1) 
sw $t3 0($t0) 

addi $t0 $t0 4 
addi $t1 $t1 -4 
blt $t0 $t1 loop 
+0

я не пришел к такому выводу .. это потому, что я не знаю, что еще делать. Как бы вы меняли значения? – compski

+0

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

+0

Я попытался перевести точно с использованием третьей переменной, но у меня есть проблема с увеличением и уменьшением адреса источника ..., поэтому я должен использовать 2 массива вместо 1? Вы меня понимаете? может быть, это будет проще, если вы просто покажете мне исправления – compski

Смежные вопросы