C в MIPS Десятичный в двоичный преобразователь с использованием рекурсии - PullRequest
0 голосов
/ 10 мая 2018

Я новичок в 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

Моя главная проблема - не знать, как использовать syscall и не понимать рекурсивную функцию в MIPS.,Пожалуйста, укажите мои ошибки и ошибки!

1 Ответ

0 голосов
/ 10 мая 2018

ваши системные вызовы 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 содержит "функцию системного вызова" или, на английском языке, нужную вам услугу:операционная система для выполнения. Здесь есть их таблица.

$a0 будет содержать первый параметр, переданный в вызов.Чтобы установить этот параметр, одним из методов является добавление входного значения к нулю, сохраняя результат в $a0. Вот почему у вас так много строк, как этот

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

Наконец, системные вызовы, которые вы используете: (4=> print String, 5 => read integer, 1 => print integer и 10 => exit)

Поэтому правильно прокомментированный пример вашего кода будет иметь вид

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, из десятичного числа.Как правило, это включает в себя разбиение десятичного числа в цикле, вывод на печать нуля или единицы в каждом из двоичных чисел.Поскольку для этого потребуется цикл для каждого заполнителя в двоичном числе, не представляется возможным, чтобы один вызов «print integer» был возможен (если только ввод не был ограничен только десятичными «1» и «0», иливход ограничен таким небольшим числом, что его двоичное представление, представленное в десятичном формате, меньше, чем max_int).

Таким образом, для входа 5 желаемый вывод будет 101, и это будет 3 вызовапечатать в порядке «1», «0», «1».Я считаю, что такой подход печати цифр в цикле даст вам больший успех и позволит вам печатать каждое введенное положительное десятичное число.

Короче говоря, я думаю, что ваша команда syscall в порядке, но вывсе еще борется с тем, как делать петли и решать проблемы при сборке.Попробуйте выяснить, как вы будете определять цифры в нужном порядке вручную, используя карандаш и бумагу, а затем попытайтесь закодировать это в своей программе.

...