从C语言到MIPS的解释

时间:2018-11-07 09:42:04

标签: c assembly mips

我想创建一个MIPS程序。 这是我的C代码,如下所示:

import dash_core_components as dcc

dcc.Dropdown(
    id='column-plot-list',
    options=[{'label': i, 'value': i} for i in ['opt1', 'opt2']],
    value='opt1',
    multi=True,
    clearable=False
)

然后下面显示的代码是我如何从C转换为MIPS:

#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");
    }
}

一开始,尽管我确实创建了预期的结果,即要求用户插入输入的随机数,但仍存在一个即将到来的问题,即循环未成功遍历整个程序。我陷入了循环1。

1 个答案:

答案 0 :(得分:-1)

您的逻辑在某些地方是不正确的,注释也是错误的,这很可能是造成混乱的主要原因。

我看到的问题(希望不丢失任何问题)

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和row的变量
  • 您想为I和j以及row分配一个寄存器,因此不需要将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)和row(s3)而不是s0。
  • addi $ s1,$ s1,1应该在循环2完成之后,因为在循环2 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 ++)
  • 需要打印换行符,并在loop2的末尾从loop1递增I,因此需要先跳到中间步骤,然后再返回loop1

下一步:

li  $v0, 1          # read_double => scanf("%d")
move $a0, $t0        # move register to be printed into argument register $a0
syscall
  • 对li的注释有误-其打印方式
  • 您还需要在打印后增加j

下一个:

  • 在loop2结束后您不打印换行符

所有这些更改使我得到了

  .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