Related
Greedings,
I am working on an MIPS project in Mars. Sadly it looks like, I don't understand correctly how MIPS works.
For example: I have the Register $a0 with the baseaddress of an array and in register $a1 is the length of the array.
Every element in the array is a halfword. I want to shift a element one postion if the number before is a zero. E.g. 2 0 2 0 4 => 2 2 0 4 0
The problem is, that my program doesn't even load the right Elements from the array.
.text
.global move_one
move_one:
addiu $sp $sp -12
sw $a0 8($sp)
sw $a1 4($sp)
sw $a2 0($sp)
li $v0 0
b loop
loop:
addiu $a1 $a1 -1
beqz $a1 end
lhu $a2 0($a0)
addiu $a0 $a0 2
beqz $a2 shift
b loop
shift:
lhu $a2 0($a0)
sh $a2 -2($a0)
sh $zero 0($a0)
li $v0 1
b loop
end:
lw $a0 8($sp)
lw $a1 4($ap)
lw $a2 0($ap)
addiu $sp $sp 12
jr $ra
With my tests I found out, that shift never get called and $a2 have different values over the runningtime, also 0.
I hope I could make my problem clear.
I am really thankful for any help.
Edit:
.data
.globl main
message:
.asciiz "move_one returned: "
board:
.half 0,0,2,0
.half 0,0,0,0
.half 0,0,0,0
.half 0,0,0,0
buf:
.word 0,0,0,0
.text
main:
la $t0 board
la $t1 buf
sw $t0 0($t1)
addiu $t0 $t0 2
sw $t0 4($t1)
addiu $t0 $t0 2
sw $t0 8($t1)
addiu $t0 $t0 2
sw $t0 12($t1)
la $a0 buf
la $a1 4
jal move_one
move $t0 $v0
la $a0 message
li $v0 4
syscall
move $a0 $t0
li $v0 1
syscall
li $v0 11
li $a0 10
syscall
li $a1 16
la $a0 board
jal print_board_test
li $v0 10
syscall
I was hoping that I could get some help debugging some code. I am going to try to not make this a It is for a MIPS assembly project in recursion. The program is only supposed to print prime numbers.
The idea is I have two arrays, one that lists every whole number up to 110, and the other as a flag array that is initialized to all ones.
For every position in the flag array that is a 1 it prints the number and every 0 it doesn't print the number. The good news is I figured out issues with all my loops, the issue I am having is saving the value 0 to the flag array at the position it currently is. Everything that I reference talks about using:
sw [register], ([register])
From what I understand that is how you save the contents of one register to the position of the other? It doesn't seem to work for me. I went ahead and posted the code down bellow, It is kind of messy and really long, but my code for recursion is down where it says Eratosthenes.
.data
NUM_ARRAY: .space 800 # 800-byte memory space
FLAG_ARRAY: .space 800 # 800-byte memory space
START_MSG: .asciiz "The prime numbers up to 110 are:\n"
END_MSG: .asciiz "Completed ...."
SPACE: .asciiz " "
NEWLINE: .asciiz "\n"
BUG1: .asciiz "Out of loop"
INK: .asciiz "incrementK"
INX: .asciiz "incrementX"
.text
.globl main
# THE BEGINNING OF MODULE MAIN #######################
main:
# save the ten registers --------------------------
subu $sp, $sp, 48 # stack frame for 12 registers
sw $ra, ($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $s2, 12($sp)
sw $s4, 16($sp)
sw $s5, 20($sp)
sw $t0, 24($sp)
sw $t1, 28($sp)
sw $t2, 32($sp)
sw $v0, 36($sp)
sw $a0, 40($sp)
# initialize the essential parameters -------------
li $s0, 111 # the largest number (always - 1)
li $s1, 10 # the square-root of $s0 register
li $s2, 2 # the initial value for "k"
li $s4, 0 # the first numbers to consider
li $s5, 1 # '1' - it is a prime number
li $t2, 0 # loop ounter
# show an opening message ---------------------------------
li $v0, 4 # system call #4
la $a0, START_MSG
syscall
# initialize the two arrays -------------------------------
la $t0, NUM_ARRAY # set the address of the 1st array
la $t1, FLAG_ARRAY # set the address of the 2nd array
loop1: sw $s4, ($t0) # load a number
sw $s5, ($t1) # load the initial property (1 - a prime)
addi $t2, $t2, 1 # increase the loop counter by one
beq $t2, $s0, EXIT1 # if all the array elements are set up
addi $s4, $s4, 1 # increase the number by one
addu $t0, $t0, 4 # increase the pointer by four bytes
addu $t1, $t1, 4 # increase the pointer by four bytes
j loop1 # repeat to "loop1"
EXIT1: li $s2, 2
li $s6, 2
jal Eratosthenes # start recursive Eratosthenes
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
li $t2, 0 # reset the loop counter
la $t0, NUM_ARRAY # reset the address of the 1st array
la $t1, FLAG_ARRAY # reset the address of the 2nd array
loop3: lw $a0, ($t1) # load the number there
beq $a0, $zero, SKIP1 # if the target is '0': skip
beq $t2, $zero, SKIP1 # if repeated enough: skip
li $v0, 1 # system call #1
lw $a0, ($t0) # load the number there
syscall
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
SKIP1: addi $t2, $t2, 1 # increase the loop counter
addu $t0, $t0, 4 # increase the pointer by four bytes
addu $t1, $t1, 4 # increase the pointer by four bytes
blt $t2, $s0, loop3
li $v0, 4 # system call #4
la $a0, END_MSG
syscall
# restore registers ---------------------------------------
lw $ra, ($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
lw $s2, 12($sp)
lw $s4, 16($sp)
lw $s5, 20($sp)
lw $t0, 24($sp)
lw $t1, 28($sp)
lw $t2, 32($sp)
lw $v0, 36($sp)
lw $a0, 40($sp)
addu $sp, $sp, 48 # delete the stack frame
jr $31 # park it at the parking spot
# THE END OF MODULE MAIN ##########################################
Eratosthenes:
subu $sp,$sp,36
sw $ra, 0($sp)
sw $t5, 4($sp)
sw $t6, 8($sp)
sw $t0, 12($sp)
sw $t1, 16($sp)
sw $t2, 20($sp)
sw $s4, 24($sp)
sw $s5, 28($sp)
sw $s0, 32($sp)
li $s5, 0 #change s5 to 0
li $s6, 2 #reset the x
li $t2, 0
la $t0, NUM_ARRAY #reset Array 1
la $t1, FLAG_ARRAY #reset Array 2
R_Loop:
mult $s2,$s6
mflo $t7
addi $t2,$t2,1
lw $s4, ($t0)
beq $t7, $s4, SKIPone
beq $t2, $s0, EXITL #branch if counter is max
addu $t0, $t0, 4 #next spot in NUM_ARRAY
addu $t1, $t1, 4 #next spot in FLAG_ARRAY
li $v0,1
move $a0, $t7
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
j R_Loop
SKIPone:
addi $s6,$s6,1 #increment x by one
sw $zero, ($t1) #attempt at making position at array 0
#have also tried
#sw $s5, ($t1) #where s5 is initialized at 0
#please take note that offset is 0, because it needs to be
#at the current position at the array
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,1
move $a0, $t4 #debug aid
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
beq $t2 $s0, EXITL
li $v0, 4
la $a0, INX #debug aid
syscall
j R_Loop
EXITL:
li $t8,10
li $v0, 4
la $a0, INK #debug aid
syscall
beq $s2,$t8, EXITR
addi $s2,$s2,1 #increment k by one
jal Eratosthenes
li $v0 4
la $a0, BUG1
syscall
EXITR:
lw $ra, 0($sp)
lw $t5, 4($sp)
lw $t6, 8($sp)
lw $t0, 12($sp)
lw $t1, 16($sp)
lw $t2, 20($sp)
lw $s4, 24($sp)
lw $s5, 28($sp)
lw $s0, 32($sp)
addu $sp,$sp,36
jr $ra
Any help is appreciated, nothing else seems to work and my teacher is of no help.
Down below is my code from a MIPS hw assignment where we have to multiply two matrixes. Our task was to implement the matrix_multiply function and matrix_print function
.data
matrix_a: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
matrix_b: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
result: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
newline: .asciiz "\n"
tab: .asciiz "\t"
#############################################################################
#############################################################################
## Text segment
#############################################################################
#############################################################################
.text # this is program code
.align 2 # instructions must be on word boundaries
.globl main # main is a global label
.globl multiply
.globl matrix_multiply
.globl matrix_print
.globl matrix_ask
#############################################################################
matrix_ask:
#############################################################################
# Ask the user for the current matrix residing in the $a0 register
sub $sp, $sp, 4
sw $ra, 0($sp)
# init our counter
li $t0, 0
# t1 holds our the address of our matrix
move $t1, $a0
ma_head:
# if counter less than 16, go to ma_body
# else go to exit
li $t2, 16
blt $t0, $t2, ma_body
j ma_exit
ma_body:
# read int
li $v0, 5
syscall
li $t2, 4
# ints are 4 bytes
multu $t0, $t2
mflo $t2
add $t2, $t2, $t1
sw $v0, 0($t2)
j ma_latch
ma_latch:
addi $t0, $t0, 1
j ma_head
ma_exit:
lw $ra, 0($sp)
add $sp, $sp, 4
jr $ra
#############################################################################
main:
#############################################################################
# alloc stack and store $ra
sub $sp, $sp, 4
sw $ra, 0($sp)
# load A, B, and result into arg regs
la $a0, matrix_a
jal matrix_ask
la $a0, matrix_b
jal matrix_ask
la $a0, matrix_a
la $a1, matrix_b
la $a2, result
jal matrix_multiply
la $a0, result
jal matrix_print
# restore $ra, free stack and return
lw $ra, 0($sp)
add $sp, $sp, 4
jr $ra
##############################################################################
multiply:
##############################################################################
# mult subroutine $a0 times $a1 and returns in $v0
# start with $t0 = 0
add $t0,$zero,$zero
mult_loop:
# loop on a1
beq $a1,$zero,mult_eol
add $t0,$t0,$a0
sub $a1,$a1,1
j mult_loop
mult_eol:
# put the result in $v0
add $v0,$t0,$zero
jr $ra
##############################################################################
matrix_multiply:
##############################################################################
# mult matrices A and B together of square size N and store in result.
# alloc stack and store regs
sub $sp, $sp, 24
sw $ra, 0($sp)
sw $a0, 4($sp)
sw $a1, 8($sp)
sw $s0, 12($sp)
sw $s1, 16($sp)
sw $s2, 20($sp)
add $t5, $zero, $zero #Set t5 to zero. i = 0
add $t6, $zero, $zero #Set t6 to zero. j = 0
add $t7, $zero, $zero #Set t7 to zero. k = 0
#setup for i loop
iLoop:
beq $t5, 4, exit
j jLoop
#setup for j loop
jLoop:
beq $t6, 4, iEnd
#setup for k loop
kLoop:
beq $t7, 4, jEnd
# compute A[i][k] address and load into $t3
# A[i][k] = A+4*((4*i) + k)
sll $t3, $t5, 2 # Store 4*i in $t3
addu $t3, $t3, $t7 # Adds $t3 to k
sll $t8, $t3, 2 # Computes 4*($t3) = 4*(4*i+k) by temporarily storing the product in $t8
move $t3, $t8 # Stores 4*($t3) into $t3
addu $t3, $t3, $a0 # Adds A to $t3
lw $t3 0($t3)
# compute B[k][j] address and load into $t4
# B[k][j] = B+4*((4*k) + j)
sll $t4, $t7, 2 # Stores 4*k in $t3
addu $t4, $t4, $t6 # Adds $t4 to j
sll $t8, $t4, 2 # Computes 4*($t4) = 4*(4*k+j) by temporarily storing the product in $t8
move $t4, $t8 # Stores 4*($t4) into $t4
addu $t4, $t4, $a1 # Adds B to $t4
lw $t4 0($t4)
# call the multiply function
multu $t3, $t4
mflo $t9
# compute RESULT[i][j] address and load into $t1
# RESULT[i][j] = RESULT+4*((4*i) + j)
sll $t1, $t5, 2 # Store 4*i in $t1
addu $t1, $t1, $t6 # Adds $t1 to j
sll $t8, $t1, 2 # Computes 4*($t1) = 4*(4*i+k) by temporarily storing the product in $t8
move $t1, $t8 # Stores 4*($t1) into $t1
addu $t1, $t1, $a2 # Adds A to $t3
lw $t1 0($t1)
sw $a2 0($t9) # Store $t9 into its respective location in $a2
# increment k and jump back or exit
addi $t7, $t7, 1
j kLoop
jEnd:
#increment j and jump back or exit
addi $t6, $t6, 1
li $t7, 0
j jLoop
iEnd:
#increment i and jump back or exit
addi $t5, $t5, 1
li $t6, 0
j iLoop
exit:
# retore saved regs from stack
lw $s2, 20($sp)
lw $s1, 16($sp)
lw $s0, 12($sp)
lw $a1, 8($sp)
lw $a0, 4($sp)
lw $ra, 0($sp)
# free stack and return
add $sp, $sp, 24
jr $ra
##############################################################################
matrix_print:
##############################################################################
# alloc stack and store regs.
sub $sp, $sp, 16
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $a0, 12($sp)
li $t0, 4 # size of array
# do your two loops here
# setup to jump back and return
lw $ra, 0($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
lw $a0, 12($sp)
add $sp, $sp, 16
jr $ra
I keep getting one of the two following errors - Either I get an error saying Exception occurred at PC=0x004000cc, Arithmetic overflow or "The Following Symbols are Undefined" and it lists iEnd, matrix_print, exit, and jEnd. I don't know why those symbols would be "undefined since they're clearly written in my code, and they don't have to be "global" symbols, otherwise matrix_print wouldn't have been included in that list.
I realize I haven't yet implemented my matrix_print, but I'll get to that once I figure out what's causing the more pressing issue, which is my Arithmetic Overflow error. I use sll knowing I need to multiply by 4, and sll is the best way to approach it. I don't believe I'm going out of bounds anywhere either, so if someone can please help me debug this I would greatly appreciate it. Thanks!
I'm working on a sorting program that sorts an array of integers, for which I copy the array entered in by the user into a new array to be mutated. However, I'm not sure if I'm doing it correctly.
.globl main
.data
input: .asciiz "Enter the size of the array: \n"
entries: .asciiz "Enter the elements of the array, one line at a time: \n"
output: .asciiz "Original array and then sorted array: \n"
space: .asciiz " "
.text
main:
subi $sp, $sp 32
sw $ra, 0($sp)
sw $t0, 4($sp) # the size of the array
sw $t4, 8($sp) # the number 4
sw $t1, 12($sp) # temporary
sw $t2, 16($sp) # array original
sw $t3, 20($sp) # specific element
sw $s1, 24($sp) # copied array
sw $t5, 28($sp) # number to copy
la $a0, input
li $v0, 4
syscall
# get the size
li $v0, 5
syscall
move $t0, $v0
# allocate space for the array on the heap
li $t4, 4
mul $t1, $t0, $t4
li $v0, 9
move $a0, $t1
syscall
move $t2, $v0
li $s0, 0
la $a0, entries
li $v0, 4
syscall
read_array:
# read element
li $v0, 5
syscall
move $t3, $v0
# place in right address
mul $t1, $s0, $t4
add $t1, $t2, $t1
sw $t3, 0($t2)
addi $s0, $s0, 1
blt $s0, $t0, read_array
li $s0, 0
gnome_sort:
# allocate space on heap for copy
mul $t1, $t0, $t4
li $v0, 9
move $a0, $t1
syscall
move $s1, $v0
mul $s2, $t4, $t0
add $s3, $s1, $s2
copy_array:
lw $t5, 0($t2)
sw $t5, 0($s1)
add $t2, $t2, $t4
add $s1, $s1, $t4
blt $s1, $s3, copy_array
li $s0, 0
while_loop:
bgt $s0, $t0, finish_sort
beq $s0, $zero, increase_i
sw $s4, 0($s1)
sw $s5, -4($s1)
bge $s4, $s5, increase_i
j swap_elements
increase_i:
addi $s0, $s0, 1
j while_loop
swap_elements:
la $a0, input
li $v0, 4
syscall
sw $t6, 0($s1)
sw $t7, -4($s1)
lw $t7, 0($s1)
lw $t6, -4($s1)
subi $s0, $s0, 1
j while_loop
finish_sort:
li $s0, 0
la $a0, output
li $v0, 4
syscall
j print_original
print_original:
bge $s0, $t0, print_sorted
lw $s6, 0($t2)
li $v0, 1
move $a0, $s6
syscall
la $a0, space
li $v0, 4
syscall
addi $s0, $s0, 1
j print_original
print_sorted:
li $s0, 0
loop:
bge $s0, $t0, finish
lw $s6, 0($s1)
li $v0, 1
move $a0, $s6
syscall
la $a0, space
li $v0, 4
syscall
addi $s0, $s0, 1
j loop
finish:
li $v0, 10
syscall
After testing this in QTSpim, it seems that you're going out of allocated memory on the line sw $s4, 0($s1)
in the while_loop. This is because $s1 at that point is past the end of the second array you allocated. If you want to use that memory, you will have to syscall for it.
The way you copy the array using lw and sw is correct.
Can someone tell me the problem in this one?
`#initializing indexes i,j,k
addi $s0, $zero, 0
addi $s1, $zero, 0
addi $s2, $zero, 0
addi $sp, $sp, -16
sw $s0, 0($sp)
sw $s1, 4($sp)
sw $s2, 8($sp)
while1:
bgt $s0,2,exit1
while2:
sw $ra, 12($sp)
bgt $s1,2,exit2
addi $s1,$s1,1
while3:
sw $ra, 12($sp)
bgt $s2,2,exit3
mul $t0,$s0,$s0
add $t1,$t0,$s1
sll $t2,$t1,3
add $t3,$t2,$a0
add $t4,$t2,$a1
add $t5,$t2,$a2
ldc1 $f4, ($t3)
ldc1 $f6, ($t4)
ldc1 $f8, ($t5)
mul.d $f8,$f6,$f4
sdc1 $f8, ($t5)
addi $s2,$s2,1
j while3
addi $s1,$s1,1
j while2
addi $s0,$s0,1
j while1
exit1:
lw $s0, 0($sp)
addi $sp, $sp, 16
jr $ra
exit2:
lw $s1, 4($sp)
jr $ra
exit3:
lw $s1, 8($sp)
jr $ra
addi $t2,$zero,0
while:
beq $t2,24,exit
ldc1 $f2, 0($a2)
li $v0, 3
add.d $f12,$f2,$f0
syscall
addi $t2,$t2,8
li $v0, 10
syscall
It tells me Exception occurred at PC=0x000000 , Bad address in text read: 0x0000000 and attempt to execute a non-instruction at 0x80000180..
What i want to do is to multiply matrixes A and B and store the result in a third matrix C. The matrixes A,B and C are in the addresses $a0, $a1 and $a2