Почему это работает?Печать массива в обратном порядке в MIPS - PullRequest
0 голосов
/ 03 марта 2019

У меня есть проект для класса, и все идет хорошо.Нам просто нужно было хранить 20 целых чисел из пользовательского ввода в массиве и печатать их различными способами.Мой код работал, печатая его в правильном порядке, но когда я делал это в обратном порядке, вывод был довольно странным.Так что, не понимая, я вроде понял, суть в том, что индекс был проблемой, и по какой-то причине я решил ее?Но я не понимаю, если это действительно правильно.

    # for reverse order that worked
    addi $t0, $zero, 76
    while:

        beq $t0, -4, exit

        lw $t1, inputArray($t0)

        li $v0, 1
        move $a0, $t1
        syscall

        li $v0, 4 
        la $a0, space
        syscall

        addi $t0, $t0, -4

        j while

Теперь вот что я сделал в первый раз:

     # reverse order that didn't work
     addi $t0, $zero, 76
     while:

        beq $t0, 0, exit

        lw $t1, inputArray($t0)

        li $v0, 1
        move $a0, $t1
        syscall

        li $v0, 4 
        la $a0, space
        syscall

        addi $t0, $t0, -4

        j while

Вывод, когда он не работал, был:

1702129221 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2

1 Ответ

0 голосов
/ 03 марта 2019

Существует проблема даже с вашим рабочим кодом.

Действительно, использование inputArray($t1) не является правильным способом доступа к вашему массиву.Ваш код будет сломан , если адрес inputArray не может быть закодирован в 16 битах.И это делает ваш код более трудным для чтения и более подверженным ошибкам.

Что вам нужно сделать, это разделить счетчик цикла и вычисление индекса массива.Это примерно соответствует следующему псевдокоду C

for(int i=20, array=&inputArray[20]; i!=0; i--, array--){
  print(*array," ");

Asm version

    # init part :: int i=20, array=inputArray[20];
    addi $t0, $zero, 20   # $t0 is loop counter i
    li $t2, inputArray # load 32 bits address of inputArray $t2=@inputArray
    addi  $t2, 76         # $t2=array=@inputArray[20]
while:
    beq $t0, zero, exit   # loop condition :: i!=0;
    # loop body :: print  *Array, " "
    lw $t1, 0($t2)
    addi $v0,zero, 1
    move $a0, $t1
    syscall
    # print space
    addi $v0,zero, 4 
    li $a0, space
    syscall
    # loop increments :: i--, array--
    addi $t0, $t0, -1  #i--
    addi $t2, $t2, -4  #array--
    j while

Разделение цикла и доступ к массиву всегда приводит к лучшему коду.И намного проще, если вам нужно получить разные элементы массива за итерацию, например, для печати array[i]*array[i-1] или разных типов массивов intArray[i]+=shortArray[i].

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

...