raveynbleu
raveynbleu

Reputation: 13

Learning MIPS: Creating a simple program to read numbers and print them

I'm struggling with learning MIPS right now, and I'm finding it isn't as easy as C++ was.

Right now, I'm to edit/write a program that will take ten number's from a user, then print those numbers out at the end with commas between them, and no comma after the last number. Example:

Enter a number 1
Enter a number 2
Enter a number 9
Enter a number 11
Enter a number 99
Enter a number 12
Enter a number 24
Enter a number 90
Enter a number 17
Enter a number 82
1, 2, 9, 11, 99, 12, 24, 90, 7, 82

This is the given code:

    .data
    .space 40                 # set aside 40 bytes for 10 integers
prompt:
    .asciiz "Enter a number " # address 0x10010028
comma:
    .asciiz ", "              # address 0x10010038

.globl main
.text
main:
    lui $a0, 0x1001 # get start of data segment
    jal getdata     # call getdata function

    lui $a0, 0x1001 # get start of data segment
    jal print       # call print function

    ori $v0, $0, 10 # set command to exit
    syscall         # end program

getdata:
    addi $sp, $sp, -4    # allocate space on stack
    sw $ra, 0($sp)       # save $ra
    ori $t1, $a0, 0      # address of array

    lui $t1, 0x1001      # start of data
    ori $a0, $a0, 0x0028 # address of prompt
    ori $t0, $0, 10      # counter

top:
    beq $t0, $0, ret     # while not 0

    jal printstr         # call function to print prompt
    ori $v0, $0, 5       # set command to read integer
    syscall              # read int
    sw $v0, 0($t1)       # save int in memory
    addi $t1, $t1, 4     # increment to next location

    addi $t0, $t0, -1    # decrement counter
    j top                # repeat

ret:
    lw $ra, 0($sp)       # restore return address
    addi $sp, $sp, 4     # clean up stack
    jr $ra               # return from call

    # print
    # parameter: $a0 holds address of list in memory
    # purpose: print the list separated by commas
print:
    #to be completed
    jr $ra

    # printstr
    # paramters: $a0 holds address of string to print
    # purpose: print the string parameter
printstr:
    #to be completed
    jr $ra

Where I believe I'm struggling at is the "print" portion. I have the following for printstr: and for getdata:

printstr:
    ori $v0, $0, 4  # command to print string at $a0
    syscall
    jr $ra          # return from call

getdata:
    addi $sp, $sp, -4    # allocate space on stack
    sw $ra, 0($sp)       # save $ra
    ori $t1, $a0, 0      # address of array

    lui $t1, 0x1001      # start of data
    ori $a0, $a0, 0x0028 # address of prompt
    ori $t0, $0, 10      # counter

And then this is the code I've been trying to use for the loop...

print:
    addi $t2, $t2, 10
    addi $t0, $t0, 1      # Enter into the loop by increment 1
    ori $v0, $0, 4        # Print the 1st value and then loop
                          # start from the 2nd value

    syscall

    jal loop # Jump to loop

loop:
    beq $t0, $t2, end  # checks if t2=t0, if it does then ends the program
    lui $t3, 0x1001    # loads the upper limit of t3 to 1001
    or $a0, $0, $t3    # sets the upper limit of a0 to 1001
    ori $v0, $0, 1     # sets v0 to print integer
    syscall            # prints integer
    addi $t3, $t3, 4   # moves t3 to the next address

    ori $a0, $a0, 0x0038  # sets a0 to the address of comma
    ori $v0, $0, 4        # Print string at $a0
    syscall
    addi $t0, $t0, 1      # increases the value at t0 by 1
    jr $ra

However, when I run the program it spits out "268500992, ,". So I'm not getting my input numbers or the correct number of commas even. I know that means that my loop isn't running all the way through. I'm not supposed to use and pseudo code, and only what I've learned so far - so array's are out of the question.

Can someone help me figure out what I'm missing? Does it have something to do with the stack values (which I don't completely understand)?

Upvotes: 1

Views: 1359

Answers (1)

zwol
zwol

Reputation: 140788

OK, I think your code for printstr is correct, and getdata also looks fine (a little odd, but you didn't write that, yes?) The bugs are all in print. I'm not going to spell it out for you, because this is homework, but the structure of the loop in print should be very similar to the structure of the loop in getdata:

    # on entry, $a0 = address of integer array
print:
    ori $t0, $0, 10      # counter
    ori $t1, $a0, 0      # t1 points to current array element

print_loop:
    ### if this isn't the first iteration, print ", "
    ### load value at $t1 into $a0
    ### print the integer in $a0

    addi $t1, $t1, 4     # advance to next array element
    addi $t0, $t0, -1    # decrement counter
    bne  $t0, $0, print_loop

    ### print a carriage return

    jr $ra               # return from call

Each thing prefixed by ### is a placeholder for code you need to write.

Upvotes: 1

Related Questions