Устный перевод с языка Си на MIPS - PullRequest
0 голосов
/ 07 ноября 2018

Я хотел бы создать программу MIPS. Вот мой код C, показанный ниже:

#include <stdio.h>

int main()
{
    int i, j, row;

    printf("\nEnter a random row\n");
    scanf("%d", &row);

    for (i=1; i <= row; i++)
    {
        for (j=1; j <= i; j++)
        {
            printf("%d", j);
        }
        printf("\n");
    }
}

Тогда код, показанный ниже, показывает, как я перевожу с C на MIPS:

    .data
word:   .asciiz "Please enter a random row: \n"
    .text
    .globl main

main:   
    la $a0, word        # load word
    li $v0, 4           # print integer
    syscall

    addi $s0, $s0, -1    # for accommodating loop condition
    lw $s1, i           # set i = 1
    lw $s2, j           # set j = 1
    lw $s3, row     # load row


loop1:
    blt $s0, $s1, exit  # for(i = 0; i < row; i++)
    addi $s1, $s1, 1     # i++
    li $s2, 1           # resets j to 1 after every iteration of for  loop
    move $a0, $t0        # move register to be printed into argument register $a0
    j loop2            # executing the nested for loop


loop2:
    blt $s1, $s2, loop1 # for(i = 0; i < j; i++)
    li  $v0, 1          # read_double => scanf("%d")
    move $a0, $t0        # move register to be printed into argument register $a0
    syscall
    j loop2


   li $v0, 10           # loading exit code
   syscall             # execute exit

Вначале, хотя я и создал ожидаемый результат, который заключается в том, чтобы попросить пользователя вставить введенное случайное число, возникает проблема, которая заключается в том, что цикл не прошел всю программу успешно. Я застрял в петле 1.

1 Ответ

0 голосов
/ 09 ноября 2018

Ваша логика неверна в некоторых местах, и комментарии также неверны, что, вероятно, является большой частью путаницы.

Проблемы, которые я вижу (надеюсь, не пропустил ни одной):

main:   
    la $a0, word        # load word
    li $v0, 4           # print integer
  • Это строка для печати, поэтому комментарий неправильный.

  • Возможно, также из-за того, что вы не читаете целое число, которое соответствует C scanf ("% d", & row); строка, поэтому нужно добавить:

    li $v0, 5
    syscall
    move $s3, $v0
    

Далее:

addi $s0, $s0, -1    # for accommodating loop condition
lw $s1, i           # set i = 1
lw $s2, j           # set j = 1
lw $s3, row     # load row
  • не уверен, для чего нужен s0, поскольку у вас есть переменные для I, j и строки
  • вы хотите выделить регистр для I и j и строки, поэтому не нужно загружать в него I или j (у вас нет для них меток в любом случае), поэтому реальное должно быть что-то вроде:

    li $s1, 1           # set i = 1 
    li $s2, 1           # set j = 1
    
    • s3 (строка) необходимо загрузить как часть дополнения к scanf

Далее:

loop1:
    blt $s0, $s1, exit  # for(i = 0; i < row; i++)

    addi $s1, $s1, 1     # i++
  • blt $ s0, $ s1, у выхода неправильный комментарий, нет метки выхода, нужно сравнить I (s1) и строку (s3), а не s0.
  • addi $ s1, $ s1, 1 должно быть после завершения цикла 2, так как I используется в loop2 aos, если увеличение здесь будет неправильным для следующего цикла.
  • изменить на:

    loop1:
        blt $s3, $s1, exit_loop1  # for(i = 1; i <= row; i++)
    

Далее:

move $a0, $t0        # move register to be printed into argument register $a0
j loop2            # executing the nested for loop - this does nothing as next instruction is loop2
  • t0 ничего не установлено, и a0 здесь не используется, поэтому кажется бессмысленным

  • j loop2 переходит к следующей инструкции, поэтому не требуется

Далее:

loop2:
    blt $s1, $s2, loop1 # for(i = 0; i < j; i++)
  • комментарий неправильный должен быть (j = 1; j <= i; j ++) </li>
  • необходимо вывести новую строку и приращение I из цикла loop1 в конце цикла loop2, поэтому необходимо перейти к промежуточному шагу, прежде чем вернуться к loop1

Далее:

li  $v0, 1          # read_double => scanf("%d")
move $a0, $t0        # move register to be printed into argument register $a0
syscall
  • неправильный комментарий для li - его печать int
  • вам нужно также увеличить j после печати

следующая:

  • вы не печатаете новую строку после окончания цикла2

Итак, со всеми этими изменениями я получаю:

  .data
word:   .asciiz "Please enter a random row: \n"
newline: .asciiz "\n" # added
  .text
  .globl main

main:   
  la $a0, word        # load word
  li $v0, 4           # print prompt
  syscall

  # read integer scanf(%d), save to s3
  li $v0, 5
  syscall
  move $s3, $v0

  li $s1, 1           # set i = 1 for loop 1
loop1:
  blt $s3, $s1, exit_loop1  # for(i = 1; i <= row; i++)

  # set up loop2 stuff
  li $s2, 1           # resets j to 1 after every iteration of for  loop

loop2:
  blt $s1, $s2, exit_loop2 

  li  $v0, 1          # print int j
  move $a0, $s2   
  syscall

  # increment j
  addi $s2, $s2, 1 

  j loop2

exit_loop2:
  # printf("\n");
  la $a0, newline        # load newline string
  li $v0, 4         
  syscall

  # increment loop1 i
  addi $s1, $s1, 1     # i++

  j loop1

exit_loop1:
  li $v0, 10           # loading exit code
  syscall             # execute exit
...