首页 文章

使用递归的C到MIPS十进制到二进制转换器

提问于
浏览
2

我是MIPS的新手,我写了一个基本格式,我认为我写的C文件中的代码与MIPS相当 . 我的任务是将我编写的以下C文件转换为MIPS应该是什么的直接翻译 . 我目前的C代码是:

#include <stdio.h>
int d2b(int d)
{
    if(d == 0)
    {
        return;
    }
    else
    {
        return (d %2 + 10 * d2b(d/2));
    }
}

int main()
{
    int d = 99;
    int b;

    b = d2b(d);
    printf("Input => %d  \n", d);
    printf("Output => %d ", b);

    return;
}

到目前为止,我有以下内容:

.data
 msg1   .asciiz “Number is “
 msg2   .asciiz “\nConverted to \n“
.text
.globl main 

main:
    li $v0, 4        
    la $a0, msg1 
    syscall

    li $v0, 5      #Exit syscall
    syscall 
    add $a0, $v0, $zero
    jal fact

    add $a0, $v0, $zero
    li $v0, 1
    syscall

    li $v0, 10
    la $a0, msg2 
    syscall


fact:   
    li      $t0     0               #load 0
    beq     $a0,    $t0,    skip    #test n
    li      $v0 0
    jr      $ra
skip:   
    subu    $sp,    $sp, 32
    sw      $ra     20($sp)
    sw      $fp,    16($sp)
    addiu   $fp,    $sp, 28
    sw      $a0,    0($fp)      #save n
    li      $t1 2               #load 2
    divu    $a0 $t1             #n / 2
    mfhi    $t2                 #remainder
    mflo    $t3                 #quotient
    move    $a0,    $t3         #n = quotient
    addi    $v0,    $a1,    10
    jal     fact
    lw      $a0,    0($fp)      #restore n
    multu   $v0,    $a0 
    lw      $ra,    20($sp)
    lw      $fp,    16($sp)
    addiu   $sp,    $sp,    32
    jr      $ra

我的主要问题是不知道如何使用系统调用而不是真正理解MIPS中的递归函数 . 请指出我的错误和错误!

1 回答

  • 1

    您的MIPS系统调用在本节中

    li $v0, 4        
    la $a0, msg1 
    syscall
    
    li $v0, 5      #Exit syscall
    syscall 
    add $a0, $v0, $zero
    jal fact
    
    add $a0, $v0, $zero
    li $v0, 1
    syscall
    
    li $v0, 10
    la $a0, msg2 
    syscall
    

    他们的评论不正确

    在MIPS系统调用中,$ v0保存"syscall function"或英文,即您希望操作系统执行的服务 . There's a table of them here.

    $a0 将保存传递给调用的第一个参数 . 要设置此参数,一种方法是将输入值添加到零,将结果存储到 $a0 这就是为什么你有这么多像这样的行

    add $a0, $v0, $zero # this adds $v0 to the number zero and storing in $a0
    

    最后,您使用的系统调用是(4 => print String,5 =>读取整数,1 =>打印整数,10 =>退出)

    因此,您的代码的正确评论示例将是

    la $a0, msg1         # load string as parameter
    li $v0, 4            # load operation "print string"
    syscall              # request "print string" for msg1
    
    li $v0, 5            # load operation "read integer"
    syscall              # request "read integer"
    add $a0, $v0, $zero  # load the read integer into $a0 
    jal fact
    
    add $a0, $v0, $zero  # load the value of $v0 into $a0
    li $v0, 1            # load operation "print integer"
    syscall              # request "print integer"
    

    正如您所看到的,我的困惑不是来自您使用系统调用的能力,而是来自您对使用系统调用的内容的描述 .

    您声明要从十进制输入中打印二进制数字,如 01001010 . 这通常涉及在循环中打破十进制数,在每个二进制数位置打印出零或一 . 由于这将需要二进制数中每个占位符的循环,因此它不会以十进制格式表示的小于max_int的二进制表示形式 .

    因此,对于5的输入,期望的输出将是101,并且将是3次打印调用,按照“1”,“0”,“1”的顺序 . 我相信这种在循环中打印数字的方法会给你更大的成功,并允许你打印输入的每个正十进制数 .

    简而言之,我认为你对系统调用的命令很好,但是你仍然在努力解决如何循环和解决汇编问题 . 尝试弄清楚如何使用铅笔和纸张手动确定所需顺序的数字,然后尝试将其编码到您的程序中 .

相关问题