Моя программа MIPS верна? - PullRequest
4 голосов
/ 18 апреля 2009

Напишите программу MIPS, которая генерирует и складывает все четные числа от 1 до 100.

  • должно иметь хотя бы одну петлю
  • должна хранить сумму в регистре R12

И вот что я написал:
main:
    li      $t0, 0               # clear register $t0 to zero
    li      $t4, 0               # clear register $t4 to zero
loop:
    add     $t0, $t0, 2          # generating even numbers in register $t0
    add     $t4, $t4, $t0        #  compute the sume
    bne     $t0, 100, loop       # if t0 reached 100 then go to loop.
    b endloop                    # branch to endloop
endloop:
    li      $v0, 10              # terminate program run and
    syscall                      # Exit 

Это правильно?

Ответы [ 4 ]

10 голосов
/ 18 апреля 2009

Я только что закончил свой класс сборки MIPs, и у меня есть для вас предложение: Не используйте PC Spim!

Я использовал PC Spim, Mars и Qemu, и лучшим для общей курсовой работы является Mars (Mips Assembler и Runtime Simulator) . Редактор хорош, он падает на намного * на 1008 * меньше и позволяет легко отлаживать и устанавливать точки останова. Он бесплатный, с открытым исходным кодом и создан государственным университетом штата Миссури.

Он поставляется в виде файла .jar, поэтому вы можете запускать его как в Windows, так и в Linux. alt text
[ Mars Mips Emulator ]

В общем случае, простой способ определить, является ли число четным или нечетным, - это AND (поразрядно) 1 с номером, а если результат равен 0, то число является четным.

Однако, поскольку нам нужны все четные числа в серии, мы можем просто зациклить и увеличить наше число на 2, как вы делали в опубликованном коде.

При добавлении немедленного значения вы должны использовать инструкции «addi» или «addu», а не «add». Вы также сказали, что хотите поместить результат в регистр $ r12, но это недопустимый регистр MIP. Проверьте ссылку MIPs на Википедию, чтобы увидеть список всех регистров: MIPS - Использование регистра.

Я изменил вашу программу для правильной работы. Он сохраняет окончательный результат в $ t1 и затем печатает окончательный результат.

                .text
                .globl main
main:
    li      $t0, 0               # $t0 = loop counter
    li      $t1, 0               # $t1 = sum of even numbers
loop:
    addi    $t0, $t0, 2          # generating even numbers in register $t0
    add     $t1, $t1, $t0        #  compute the sum
    bne     $t0, 100, loop       # if t0 reached 100 then go to loop.

    li      $v0, 4
    la      $a0, result
    syscall                      # print out "Sum = "

    li      $v0, 1
    move    $a0, $t1
    syscall                      # print out actual sum


exit:
    li      $v0, 10              # terminate program run and
    syscall                      # Exit 


                .data
result:         .asciiz "Sum = "

После запуска этого на Марсе я получаю следующее:

Сумма = 2550
- программа закончила работу -

0 голосов
/ 18 апреля 2009

Код выглядит нормально. Как сказал Cunwold, "endloop" b не нужен, так как целью ветвления является первый (bne ...) переход. Хотя есть одна ошибка.

Вы используете одну и ту же инструкцию (добавить) двумя разными способами. Инструкция

add $t0,$t0,2

должно быть

addiu $t0,$t0,2

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

Итак, вот и все. Я заменил часть системного вызова фактическим возвратом функции (значение возвращается в регистр $ v0).

Надеюсь, это поможет.

Файл main.c

#include <stdio.h>

extern int addEven();

int main(){


        printf("%d\n",addEven());
        return 0;
}

Файл addEven.S (сборка)

#include <mips/regdef.h>

  /*
   * int addEven();
   * Adds even numbers between 0 and 100.
   * 0 + 2 + 4 + 6 +....+100 = 2550
   */

        .text
        .align 2
        .globl addEven

addEven:
        li      t0,0            # clear register $t0 to zero
        li      t4,0            # clear register $t4 to zero
loop:
        addiu   t0, t0,2          # generating even numbers in register $t0
        add     t4, t4,t0          #  compute the sume (R12 = t4)
        bne     t0, 100, loop      # if t0 reached 100 then go to loop.
endloop:
        move    v0,t4
        jr      ra

Я скомпилировал и связал эти файлы. Вот и все.

root@:~/stackoverflow# gcc -c -g addEven.S
root@:~/stackoverflow# gcc -c -g main.c
root@:~/stackoverflow# gcc main.o addEven.o -o prog 
root@:~/stackoverflow# ./prog 
2550
root@:~/stackoverflow#
0 голосов
/ 18 апреля 2009

Вы должны иметь возможность использовать SPIM самостоятельно. Кроме того, строка «b endloop» не нужна, потому что если вы не вернетесь обратно к началу цикла, программа «попадет в» endloop.

Загрузите SPIM здесь:
http://pages.cs.wisc.edu/~larus/spim.html

0 голосов
/ 18 апреля 2009

Попробуйте этот эмулятор. Когда я взял Computer Organization, я использовал SPIM, и его было довольно просто использовать. Вы также можете найти учебники на MIPS онлайн. Помните, Google - ваш друг.

...