lundi 25 septembre 2023

I need to translate this C++ code to MIPS Assembly (make it work on QtSpim)

This code is in C++11, and I need to translate it to MIPS Assembly so that it can run in QtSpim as a .s file:

#include <iostream>
using namespace std;

int main()
{
    int n;
    int c = 0;
    int i = 0;
    float d = 0;
    int even [10];
    float sum = 0;
    cout<<"Enter the number of values: ";
    cin>>n;
    if (n < 1 || n > 10)
    {
        goto err;
    }
    cout<<"Enter "<<n<<" integer values, one per line.\n";
    input:
    {
        cin>>even[i];
        i++;
    }
    if (i < n)
    {
        goto input;
    }
    cout<<"The even numbers are: ";
    show:
    {
        if (even[c]%2!=0)
        {
            goto ret;
        }
        if (sum == 0)
        {
            goto skip;
        }
        cout<<", ";
        skip:
        cout<<even[c];
        sum += (float)even[c];
        d++;
        ret:
        {
            c++;
            if (c < n)
            {
                goto show;
            }
        }
    }
    cout<<"\nThe average of the even numbers is: "<<(sum/d);
    goto end;
    err:
    {
        cout<<"Error: number of values should be between 1-10";
    }
    end:
    {
        return 0;
    }
}

it should produce an output like this:

Enter the number of values: 4
Enter 4 integer values, one per line.
4
6
10
3
The even numbers are: 4, 6, 10
The average of the even numbers is: 6.66667

it must work in QtSpim with no errors, and it must be a .s file

I tried translating the code and it came out like this:

    .data
prompt: .asciiz "Enter the number of values: "
valuesPrompt: .asciiz "Enter n integer values, one per line:\n"
evenNumbers: .asciiz "\nThe even numbers are:\n"
averagePrompt: .asciiz "\nThe average of the even numbers is:\n"
comma: .asciiz ","
negOne: .word -1
count: .word 0
sum: .word 0

    .globl main
    .text

main:
    # Prompt the user for the number of values
    li $v0, 4
    la $a0, prompt
    syscall

    # Read n from the user
    li $v0, 5
    syscall
    move $t0, $v0

    # Check if n is between 1 and 10
    li $t1, 1
    ble $t0, $t1, invalidInput
    li $t1, 10
    bgt $t0, $t1, invalidInput

    # Prompt the user for n values
    li $v0, 4
    la $a0, valuesPrompt
    syscall

    # Initialize loop counter
    li $t1, 0

readValuesLoop:
    # Read the next value from the user
    li $v0, 5
    syscall
    move $t2, $v0

    # Check if the value is even
    andi $t3, $t2, 1
    beqz $t3, evenNumber

    # Value is odd, continue to next iteration
    j incrementCounter

evenNumber:
    # Print the even number
    li $v0, 1
    move $a0, $t2
    syscall

    # Add the even number to the sum
    addu $t4, $t4, $t2

    # Check if it's the last even number
    li $t5, 1
    sub $t6, $t0, $t1
    beq $t5, $t6, calculateAverage

    # Print a comma separator
    li $v0, 4
    la $a0, comma
    syscall

calculateAverage:
    # Increment the loop counter
    incrementCounter:
    addiu $t1, $t1, 1

    # Check if we have processed all values
    beq $t1, $t0, doneReadingValues

    # Continue reading values
    j readValuesLoop

doneReadingValues:
    # Print even numbers message
    li $v0, 4
    la $a0, evenNumbers
    syscall

    # Print a new line
    li $v0, 4
    la $a0, "\n"
    syscall

    # Calculate average of even numbers
    divu $t4, $t0
    mthi $zero  # Clear upper 32 bits of dividend
    mflo $t4

    # Print the average
    li $v0, 2
    move $a0, $t4
    syscall

    # Print a new line
    li $v0, 4
    la $a0, "\n"
    syscall

    # Exit the program
    li $v0, 10
    syscall

invalidInput:
    # Print error message for invalid input
    li $v0, 4
    la $a0, "Invalid input. Please enter a value between 1 and 10.\n"
    syscall

    # Exit the program
    li $v0, 10
    syscall

It looks good but QtSpim gives me this message and the code does not run:

Instruction references undefined symbol at 0x00400044
  [0x00400044]  0x10200000  beq $1, $0, 0 [invalidInput-0x00400040]

Aucun commentaire:

Enregistrer un commentaire