Generate Random Move: Dots and Boxes Game: MIPS - random

I am trying to write a two player Dots and Boxes game. I am facing difficulty in generating random number for Computer and printing the same on the board.
Any assistance would be helpful.
The code for the user is working just fine but not the computer move.
computerMove:
li $a0, 0 # Set $a to int 0
li $a1, 99 # Set upperbound to 99
li $v0, 42 # Call Random Int Range
syscall
add $a0, $a0, 48 # add 48, since 0 starts at 48
li $v0, 1 # Printing $a0 to verify -- Generates wrong number
syscall
li $s0, 50 # Flag
li $s1, 97 # Setting $s1 to 'a'
beq $a0, 97, placePiece # if $a0 is 'a' then placePience
li $s1, 98 # Setting $s1 to 'b'
beq $a0, 98, placePiece # if $a0 is 'b' then placePiece
move $s1, $a0 # moving $a0 to $s1 for placePiece
bgt $a0, 57 computerMove # if $a0 greater 57 then continue
j placePiece # else placePiece
placePiece:
move $t0, $s1
# Placing Values
lb $t1, addr($t0)
lb $t2, mark($t0)
sb $t2, board($t1)
j printBoard
printBoard:
la $a0, board
li $v0, 4
syscall
beq $s0, 50, continue
j computerMove
.data
board: .ascii "\n\n . . . . 0 . 1 ."
.ascii "\n 2 3 4"
.ascii "\n . . . . 5 . 6 ."
.ascii "\n 7 8 9"
.asciiz "\n . . . . a . b .\n"
addr: .byte 6, 8, 33, 35, 37, 62, 64, 89, 91, 93, 118, 120
mark: .byte '-', '-', '|', '|', '|', '-', '-', '|', '|', '|', '-', '-'
box: .byte 34, 36, 90, 92

Related

Runtime exception at 0x0040002c: address out of range 0x00000001 in MIPS Assembler for ceasar encryption

The Programm compiles just fine but as soon as i give input this error is thrown:
"Error in line 28: Runtime exception at 0x0040002c: address out of range 0x00000001
Processing terminated due to errors."
Here ist the code for my programm:
.data
line: .space 80
.text
main:
# read line from stdin
li $v0, 8
la $a0, line
li $a1, 80
syscall
# call caesar_line
li $a0, 1
jal caesar_line
# return 0
li $v0, 0
jr $ra
caesar_line:
# save start of line
move $t0, $a0
# loop through line
loop:
# load the character from memory
move $t1, $a0
lb $a0, 0($t1)
beqz $a0, end_loop
jal caesar_char
sb $v0, 0($t1)
addi $t1, $t1, 1
move $a0, $t1
j loop
end_loop:
# print line
li $v0, 4
move $a0, $t0
syscall
jr $ra
caesar_char:
# check if c is lowercase
blt $a0, 'a', upper
bgt $a0, 'z', not_alpha
addi $a1, $a1, 'a'
jal caesar_helper
j done
upper:
# check if c is uppercase
blt $a0, 'A', not_alpha
bgt $a0, 'Z', not_alpha
addi $a1, $a1, 'A'
jal caesar_helper
j done
not_alpha:
# not an alphabetical character
move $v0, $a0
j done
caesar_helper:
# subtract base from c
sub $t0, $a0, $a2 # $t0 = c - base
# add distance + 26 to c
addi $t0, $t0, 26 # $t0 += 26
add $t0, $t0, $a1 # $t0 += distance
# calculate c % 26
li $t1, 26 # $t1 = 26
div $t0, $t1 , $t1 # $lo = c % 26
mflo $t0
# add base to c
add $v0, $t0, $a2 # $v0 = c + base
done:
jr $ra
Not even ChatGBT could find an error.
The code should shift all chars of an string by a certain amount, but as soon as it is run the error above is thrown.

i have problems to trying to add a get the median functionality in my MIPS program

i write the following MIPS program that take 10 integers from user, then output (min value, max value, and average), then i added instructions to get the median(starting from line 72, from the comment # Calculate median), every time i run the program after entering the 10 numbers i get the following exception (Runtime exception at 0x004000e0: fetch address not aligned on word boundary 0x10010005).
.data
array: .space 40 #10 X 4(byte)
prompt: .asciiz "Please enter 10 random numbers :\n"
sort: .asciiz "\nThe descending order of the numbers are :\n"
sum: .asciiz "\n\nThe Sum of all numbers are : "
average: .asciiz "\n\nThe average of all the number is : "
max: .asciiz "\n\nThe maximum number is : "
min: .asciiz "\n\nThe minimum number is : "
space: .asciiz " "
dot: .asciiz "."
median: .asciiz "\n\nThe median of the numbers is: "
.text
.globl main
main:
li $v0, 4
la $a0, prompt #print out prompt
syscall
la $s0, array #load array into register s0
LoopInput:
li $v0, 5 #input numbers
syscall
sw $v0, 0($s0) # $v0 = i
addi $s0, $s0,4 #move array position
addi $t0, $t0,1 #loop array where i++
bne $t0, 10,LoopInput #for(t1=0;t1!=10;t1++) g
la $s0, array
sub $t0, $t0,$t0
Sorting: #sorting number from big to small
beq $t1,9, ConSort #if t1=9, go to conSort
lw $s1, 0($s0) #load the number in the first location into $s1
lw $s2, 4($s0) #load the number in the second location into $s2
addi $s0, $s0, 4 #update array position
addi $t1, $t1, 1 #move array position #for(s1=0;s1!=9;s1++)
bge $s1, $s2, Sorting #if s1>s2, back to sorting
sw $s1, 0($s0) #exchange position
sw $s2, -4($s0)
bne $t1, 9, Sorting #if t1!=9, go back to sorting
ConSort:
la $s0, array #continue sort with the same way
addi $t0, $t0, 1 #keep sorting the other numbers
addi $t1, $t0, 0
bne $t0, 9, Sorting #if t0!=9, go back to sorting
li $v0, 4 #print out prompt
la $a0, sort
syscall
la $s0, array
sub $t0, $t0, $t0
PrintSort:
li $v0, 1 #print sorting
lw $a0, 0($s0)
syscall
li $v0, 4
la $a0, space #print out prompt
syscall
addi $s0, $s0, 4
addi $t0, $t0, 1
bne $t0, 10, PrintSort #if t0!=10, go to printsort
# Calculate median
li $t4, 5 # t4 = 5
la $s0, array # s0 points to the beginning of the array
add $s0, $s0, $t4 # s0 points to the middle element of the array
lw $t5, 0($s0) # t5 = array[5]
li $v0, 4 # print message
la $a0, median # message to print: "The median of the numbers is: "
syscall
move $a0, $t5 # print median value
li $v0, 1 # print integer
syscall
sub $t0, $t0, $t0
sub $t1, $t1, $t1
sub $t2, $t2, $t2
sub $t3, $t3, $t3
la $s0, array #load array number to $s0
li $v0, 4 #print out prompt
la $a0, sum
syscall
SumA:
lw $t2, 0($s0) #load first $t2 to $s0
addi $s0, $s0,4 #update the array[s0] position
add $t3, $t2, $t3 #t3=t2+t3
addi $t0, $t0, 1 #t0= i++
bne $t0, 10, SumA #if t0!=10, go back to SumAll
move $a0, $t3 #move $t3 to $a0
li $v0, 1 #print out the sum of all numbers
syscall
li $v0, 4
la $a0, average #print out prompt
syscall
addi $t6, $t6, 10 #t6=10
div $t3, $t6 #t3=t3/10
mflo $s5 #move quotient to s5
mfhi $s3 #move remainder to s3
move $a0, $s5 #move s5 to a0
li $v0, 1 #print out quotient
syscall
li $v0, 4
la $a0, dot #print out dot
syscall
move $a0, $s3 #move s3to a0
li $v0, 1 #print out remainder
syscall
la $s0, array #load array into s0
li $v0, 4 #print out prompt
la $a0, max
syscall
lw $t5, 0($s0) #load number in array into t5
move $a0, $t5 #move t5 to a0
li $v0, 1 #print out number
syscall
li $v0, 4 #print out prompt
la $a0, min
syscall
lw $t4 , 36($s0) #load number in array into t4
move $a0, $t4 #move t4 to a0
li $v0, 1 #print out number
syscall
li $v0, 10
syscall #end of program
from my understating the problem caused by an attempt to access memory at an address that is not aligned on a word boundary.
Unlike C, assembly doesn't auto-scale your pointer arithmetic/array indexing. It seems you understand this, since you always use addi $s0,$s0,4 to advance to the next entry in your array, as an int on the 32-bit MIPS hardware takes up 4 bytes. The only place you made an error was here:
li $t4, 5 # t4 = 5
la $s0, array # s0 points to the beginning of the array
add $s0, $s0, $t4 # s0 points to the middle element of the array
Presumably, you want the middle value which is actually going to require you to use li $t4, 20. I'll use a chart below to explain this. I'll assume that your array is located at memory address 0x00000000 (it isn't, but it's just to make the demonstration a bit easier.) If, for example, the user inputs the numbers 2,3,4,5,6,7,8,9,10, and 11, this is what your array would look like in memory after being sorted (assuming a little-endian CPU)
0x00000000: 02 00 00 00
0x00000004: 03 00 00 00
0x00000008: 04 00 00 00
0x0000000C: 05 00 00 00
0x00000010: 06 00 00 00
0x00000014: 07 00 00 00 (this is what you will get when you load from offset 20)
0x00000018: 08 00 00 00
0x0000001C: 09 00 00 00
0x00000020: 0A 00 00 00 (ten)
0x00000024: 0B 00 00 00 (eleven)
Now since there are an odd number of values, you're going to have to average the two in the center. So you'll load from 0($s0) and -4($s0), add them, and bit shift right once.

MIPS find end of string

I have the following mips code (running it in QTSPIM), that is supposed to count the number of characters in a string and print them.
The logic behind it is very simple but is does not work as it should. Everything goes well until it reaches the end of the string and then it continues counting even though I compare each element to $zero to find the end of string (\0).
Is there something wrong with my condition to exit the loop, or my_string does not contain \0 in the end so it won't exit?
.data
endl: .asciiz "\n"
my_string: .asciiz "thisisastring"
star: .asciiz "*"
str_end: .word 0
space: .asciiz " "
.text
.globl main
main:
la $a0, my_string
li $v0, 4
syscall
la $a0, endl
li $v0, 4
syscall
la $t0, my_string # load mystring to $t0
li $t1, 0 # make $t1 = 0, character counter
lb $t2, ($t0) # make $t2 point to the first character of "my_string"
li $t3, 1 # $t3 is the ++ register to go to the next character
li $t4, 0 # character counter
la $t5, str_end
cont:
beqz $t0, print # if \0 is found print and exit
addi $t4, $t4, 1 # increase the counter
lbu $a0, ($t0) # print current character
li $v0, 11
syscall
addi $t0, $t0, 1 # go to next char
#move $t2, $t0
j cont
print:
move $a0, $t4
li $v0, 1
syscall
j exit
exit:
li $v0, 10
syscall
The problem is in the order of the instructions, the logic of the code.
Here is the corrected version with no redundant code:
.data
endl: .asciiz "\n"
my_string: .asciiz "thisisastring"
str_end: .word 0
.text
.globl main
main:
la $a0, my_string
li $v0, 4 # print the string
syscall
la $a0, endl # print endl
li $v0, 4
syscall
la $t0, my_string # load mystring to $t0
li $t1, 0 # make $t1 = 0, character counter
lb $t2, 0($t0) # make $t2 point to the first character of "my_string"
la $t5, str_end
cont:
lb $a0, 0($t0) # print current character
beqz $a0, print # if \0 is found print and exit
addi $t1, $t1, 1 # increase the counter
addi $t0, $t0, 1 # go to next char
li $v0, 11
syscall
j cont
print:
move $a0, $t1
li $v0, 1
syscall
j exit
exit:
li $v0, 10
syscall

comparing a string in MIPS

Could someone tell me what is wrong with my code so far. I am trying to make a program that takes input from the user (roman numerals) and then converts it to integers. So far this is what I have:
.data
buffer: .space 20
onlyCaps: .asciiz "Please enter only Capital Numbers\n"
enter1: .asciiz "Number out of range. Please enter another number\n"
enter2: .asciiz "Please enter your roman numeral: "
debug: .asciiz "reach"
M: .asciiz "1000"
D: .asciiz "500"
C: .asciiz "100"
L: .asciiz "50"
X: .asciiz "10"
V: .asciiz "5"
I: .asciiz "1"
.text
main:
la $a0, onlyCaps # "Enter Only Capital numbers"
li $v0, 4
syscall
la $a0, enter2 #prompt user with "Please enter a roman numeral:"
li $v0, 4
syscall
la $a0, buffer #load byte space into address
li $a1, 3 # allot the byte space for string
li $v0, 8 #read user input, j
syscall
li $t4, 1
loop:
lb $t0, 0($a0) # Save $v0 value to $t0
beqz $t4, done # if it is equal to zero end the loop
add $a0, $a0, $t4 #increment the address
j mCheck
#while loop ends here
mCheck:
beq $t0, 'M', mChar # if $t0 equal M go to mChar
bne $t0, $t1, dCheck # move to see if equals D
dCheck:
beq $t0, 'D', dChar # if $t0 equal D go to dChar
bne $t0, $t1, cCheck
cCheck:
beq $t0, 'C', cChar # if $t0 equal C go to cChar
bne $t0, $t1, lCheck
lCheck:
beq $t0, 'L', lChar # if $t0 equal L go to lChar
bne $t0, $t1, xCheck
xCheck:
beq $t0, 'X', xChar # if $t0 equal X go to xChar
bne $t0, $t1, vCheck
vCheck:
beq $t0, 'V', vChar # if $t0 equal V go to vChar
bne $t0, $t1, iCheck
iCheck:
beq $t0, 'I', iChar # if $t0 equal I go to iChar
bne $t0, $t1, error
mChar:
la $a0, M #puts one hundred in $t3
li $v0, 4
syscall
j loop
dChar:
la $a0, D # prints out 500
li $v0, 4
syscall
j loop
cChar:
la $a0, C # prints out 500
li $v0, 4
syscall
j loop
lChar:
la $a0, L # prints out 500
li $v0, 4
syscall
j loop
xChar:
la $a0, X # prints out 500
li $v0, 4
syscall
j loop
vChar:
la $a0, V # prints out 500
li $v0, 4
syscall
j loop
iChar:
la $a0, I # prints out 500
li $v0, 4
syscall
j loop
error:
la $a0, enter1 # Print error meg. then back to main
li $v0, 4
syscall
j done
done:
li $v0, 10 # Exit
syscall
My question is how can you take input from the user and put it in $a0, and then use a while loop after that? I can't get the bytes to go to the next spot (i.e. MXX to go from M to X.) currently the program reads M, but not X. Eventually I will switch the program to sum these numbers and to also check to see if the number before is less (i.e. IV) to account for those roman numerals but I need help with the while loop first.

Sorting program with MIPS

I have some problem when I'm writing a sorting program in MIPS.
The function of this program is like this: Input 10 integers from keyboard and print them out, then sort them and print the sorted array again.
But the output is different from what I expect, some numbers are not sorted, would someone help me?
.data
str1: .asciiz "Please input integer numbers, maximum 10: \n"
str2: .asciiz "The 10 integer numbers you input are: \n"
str3: .asciiz "The numbers you entered are sorted as: \n"
array: .space 40
space: .asciiz " "
.text
.globl main
main:
la $t6, array #load the address of array into $t6
move $t7, $t6
addi $t7, $t7, 40 #point $t7 to the end of the array
jal readin
la $t6, array
la $a0, str2
li $v0, 4
syscall
jal print1 #print out the array before sort
la $t0, array #put the address of array into $t0
add $t0, $t0, 40 #put $t0 to the end of the array
move $t1, $zero #set $t1 as counter of the outerloop
li $t2, 10 #set $t2 as number of the outerloop
la $t3, array #put the address to $t3
jal innerloop
la $a0, str3
li $v0, 4
syscall
la $t3, array
#move $t7, $t3
#add $t7, $t7, 40
jal print2
li $v0, 10
syscall
innerloop:
lb $t4, 0($t3)
lb $t5, 4($t3)
bgt $t4, $t5, swap
addi $t3, $t3, 4
blt $t3, $t0, innerloop #if $t3 < $t0, keep in the innerloop to check two #neighbor numbers
jal outerloop #jump to outerloop if one round is finished
swap:
sb $t4, 4($t3)
sb $t5, 0($t3)
addi $t3, $t3, 4
#sll $t3, $t3, 2
blt $t3, $t0, innerloop #
jr $ra
outerloop:
la $t3, array
addi $t1, $t1, 1 #add the outerloop counter $t1 by one,
addi $t0, $t0, -1
blt $t1, $t2, innerloop #if $t1 < $t2, keep searching
jr $ra
readin:
la $a0, str1 #print str1
li $v0, 4
syscall
li $v0, 5 #read in the number
syscall
sb $v0, ($t6) #store the number in the array
add $t6, $t6, 4
blt $t6, $t7, readin
jr $ra
print1:
lb $a0, ($t6)
li $v0, 1
syscall
li $a0, 32
li $v0, 11 # syscall number for printing character
syscall
add $t6, $t6, 4
blt $t6, $t7, print1
jr $ra
print2:
lb $a0, ($t3)
li $v0, 1
syscall
li $a0, 32
li $v0, 11 # syscall number for printing character
syscall
add $t3, $t3, 4
blt $t3, $t0, print2
jr $ra
And the result in SPIM is like this:
Please input integer numbers, maximum 10:
44
Please input integer numbers, maximum 10:
11
Please input integer numbers, maximum 10:
33
Please input integer numbers, maximum 10:
22
Please input integer numbers, maximum 10:
66
Please input integer numbers, maximum 10:
55
Please input integer numbers, maximum 10:
99
Please input integer numbers, maximum 10:
77
Please input integer numbers, maximum 10:
88
Please input integer numbers, maximum 10:
24
The 10 integer numbers you input are:
44 11 33 22 66 55 99 77 88 24 The numbers you entered are sorted as:
11 33 22 44 55 66 77 88 24 32
Would someone please explain to me why there is a 32 in the end and why they are not sorted properly?

Resources