+1 (315) 557-6473 

Roll Pair Of Dice And Calculate The Percentage For Each Value After N Trials Using MARS Mips Assembly Assignment Solution.


Instructions

Objective
Write a program in assembly language to roll pair of dice and calculate the percentage for each value after n trials using MARS Mips assembly.

Requirements and Specifications

Write a simple assembly language function to simulate the rolling of two dice. The provided main calls the following functions:
  • Write a value returning MIPS function, getInput(), that will read a number between 1 and 100,000. Note, A MIPS function returns its integer result in $v0.
  • Write a value returning MIPS function, random(), to generate a random number using a lagged Fibonacci generator1.
  • Write a void MIPS function, throwDice(), to simulate the rolling of two dice n times. Each die can show an integer value from 1 to 6, so the sum of the values would vary from 2 to 12. The results should be stored in a two-dimension array. The first roll represents the row and the second roll represents the column. This function will call the random() function.
  • Write a MIPS assignment function, results(), to calculate sums, percentages, and display the twodimensional matrix showing the results. The numbers should be printed in a twodimensional format (see example output). All numbers in the table must be right justified (i.e., lined up on right side). Print the eleven possible different totals followed by the percent each combination occurred. For the final percentages, the sums should be computed as integers, then converted to float (single precision), divided by the roll count (also converted to single precision), and multiplied by 100.00. Due to the required formatting, this is likely the most difficult function.
Array Implementation: In assembly, multidimensional arrays are implemented as a large single dimension array. The formula for calculating two-dimensional array indexing is: addr(row,col) = baseAddr + (rowIndex * colSize + colIndex) * data_size
Screenshots of output
Roll pair dice and calculate the percentage
Source Code
# Name:
# NSHE ID:
# Section:
# Assignment: #4
# Description: MIPS assembly language program to simulate the rolling of two dice.
# CS 218
# MIPS Assignment #4
# MIPS assembly language program to simulate the rolling of two dice.
###########################################################
# data segment
.data
hdr: .ascii "MIPS Assignment #4 \n"
  .asciiz "Program to Simulate Rolling Two Dice. \n\n"
# -----
# Dice Results Matrix
dice: .word 0, 0, 0, 0, 0, 0
 .word 0, 0, 0, 0, 0, 0
 .word 0, 0, 0, 0, 0, 0
 .word 0, 0, 0, 0, 0, 0
 .word 0, 0, 0, 0, 0, 0
 .word 0, 0, 0, 0, 0, 0
rolls: .word 0
# -----
# Local variables for GetInput function.
MIN = 1
MAX = 100000
rd_hdr: .asciiz "\nDice Rolls Simulation Input Routine\n\n"
rd_rolls: .asciiz "Enter Number of Dice Rolls to Simulate: "
er_rolls: .ascii "\nError, rolls must be beween 1 and 100000\n"
  .asciiz "Please re-enter\n\n"
# -----
# Local variables for random function.
s_tbl: .word 47174, 64426, 21990, 28426, 63878
 .word 52330, 17190, 29642, 53958, 50474
 .word 18535, 8330, 17414, 58858, 26022
 .word 30026, 0
jptr: .word 16
kptr: .word 4
ltmp: .word 0
# -----
# Local variables for Result procedure.
r_hdr: .ascii "\n\n************************************\n\n"
  .asciiz "Rolls: "
r_top: .asciiz " ------- ------- ------- ------- ------- -------\n"
new_ln: .asciiz "\n"
bar: .asciiz " |"
blnks1: .asciiz " "
blnks2: .asciiz " "
blnks3: .asciiz " "
blnks4: .asciiz " "
blnks5: .asciiz " "
blnks6: .asciiz " "
colon: .asciiz ": "
colon2: .asciiz ": "
pctHdr: .asciiz "\n\nPercentages:\n"
hundred: .float 100.0
sums: .word 0 # 2s
 .word 0 # 3s
 .word 0 # 4s
 .word 0 # 5s
 .word 0 # 6s
 .word 0 # 7s
 .word 0 # 8s
 .word 0 # 9s
 .word 0 # 10s
 .word 0 # 11s
 .word 0 # 12s
###########################################################
# text/code segment
.text
.globl main
.ent main
main:
# -----
# Display main program header.
 la $a0, hdr
 li $v0, 4
 syscall # print header
# -----
# Get user input.
 jal getInput
 sw $v0, rolls
# -----
# Throw the dice 'rolls' times, track results.
 la $a0, dice
 lw $a1, rolls
 jal throwDice
# -----
# Calculate totals, compute percentages, and display results
 la $a0, dice
 lw $a1, rolls
 jal results
# -----
# Done, terminate program.
 li $v0, 10
 syscall
.end main
######################################################
# Procedure to read a number between between 1 and 100,000.
# Returns its result in $v0.
# YOUR CODE GOES HERE
.globl getInput
.ent getInput
getInput:
 la $a0, rd_hdr # show input title
 li $v0, 4
 syscall
 la $a0, rd_rolls # prompt user to enter a number
 li $v0, 4
 syscall
 li $v0, 5 # read number
 syscall
 blt $v0, MIN, badRolls # if < MIN, it's a bad number
 ble $v0, MAX, goodRolls # if <= MAX, it's a good number
badRolls:
 la $a0, er_rolls # print error string
 li $v0, 4
 syscall
 j getInput # read input again
goodRolls:
 jr $ra # return input value
.end getInput
######################################################
# Function to generate pseudo random numbers using
# the lagged Fibonacci generator.
# Since function, returns result in $v0.
# Algorithm:
# itmp = s_table(jptr) + s_table(kptr)
# s_table(jptr) = itmp mod 2^16
# jptr = jptr - 1
# kptr = kptr - 1
# if ( jptr < 0 ) jptr = 16
# if ( kptr < 0 ) kptr = 16
# rand_dice = ( itmp / 100 ) mod 6
# -----
# Arguments:
# none
# Returns:
# $v0
# YOUR CODE GOES HERE
.globl random
.ent random
random:
 lw $t0, jptr # load current j position
 sll $t1, $t0, 2 # j*4
 lw $t2, s_tbl($t1) # load s_table(jptr)
 lw $t3, kptr # load current k position
 sll $t4, $t3, 2 # k*4
 lw $t5, s_tbl($t4) # load s_table(kptr)
 add $t2, $t2, $t5 # itmp = s_table(jptr) + s_table(kptr)
 andi $t6, $t2, 0xFFFF # itmp mod 2^16
 sw $t6, s_tbl($t1) # s_table(jptr) = itmp mod 2^16
 addi $t0, $t0, -1 # jptr = jptr - 1
 addi $t3, $t3, -1 # kptr = kptr - 1
 bgez $t0, ifk # if (jptr < 0)
 li $t0, 16 # jptr = 16
ifk:
 bgez $t3, rnd # if (kptr < 0)
 li $t3, 16 # kptr = 16
rnd:
 sw $t0, jptr # save jptr
 sw $t3, kptr # save kptr
 div $t2, $t2, 100 # itmp/100
 li $t0, 6 # divide by 6
 div $t2, $t0 # itmp/100 / 6
 mfhi $v0 # return ( itmp / 100 ) mod 6
 jr $ra
.end random
######################################################
# Procedure to simulate the rolling of two dice n times.
# Each die can show an integer value from 1 to 6, so the sum of
# the values will vary from 2 to 12.
# The results are stored in a two-dimension array.
# Calls the Random() function.
# -----
# Formula for multiple dimension array indexing:
# addr(row,col) = base_address + (rowindex * col_size + colindex) * element_size
# -----
# Arguments
# $a0 - address of dice two-dimension array
# $a1 - number of 'rolls'
# YOUR CODE GOES HERE
.globl throwDice
.ent throwDice
throwDice:
 addi $sp, $sp, -8 # allocate space in stack to save registers
 sw $ra, 0($sp) # save return address
 sw $s0, 4($sp) # save $s0
throwLoop:
 jal random # throw first dice
 move $s0, $v0 # save generated number (row)
 jal random # throw second dice, $v0 is column
 mul $s0, $s0, 6 # multiply rowindex* col_size
 add $s0, $s0, $v0 # add rowindex* col_size + colindex
 sll $s0, $s0, 2 # multiply by 4 (element size)
 add $s0, $s0, $a0 # add base_address to get addr(row,col)
 lw $t0, 0($s0) # load old count
 addi $t0, $t0, 1 # increment count
 sw $t0, 0($s0) # update count
 addi $a1, $a1, -1 # decrement number of rolls
 bnez $a1, throwLoop # if not zero, throw another one
 lw $ra, 0($sp) # load return address
 lw $s0, 4($sp) # load $s0
 addi $sp, $sp, 8 # remove allocated space from stack
 jr $ra
.end throwDice
######################################################
# Procedure to calculate sums, percentages, and display the
# two-dimensional matrix showing the results.
# Arguments:
# $a0 - starting address of dice matrix
# $a1 - number of rolls
.globl results
.ent results
results:
# YOUR CODE GOES HERE
 move $t0, $a0 # save matrix address
 move $t1, $a1 # save number of rolls
 la $a0, r_hdr # display header
 li $v0, 4
 syscall
 move $a0, $t1 # print number of rolls
 li $v0, 1
 syscall
 la $a0, new_ln # display newline
 li $v0, 4
 syscall
 syscall # double newline
 la $a0, r_top # display top line
 li $v0, 4
 syscall
 mtc1 $t1, $f1 # convert number of rolls
 cvt.s.w $f1, $f1 # convert to float
 li $t1, 0 # start in row 0
dispRow:
 la $a0, bar # display initial column bar
 li $v0, 4
 syscall
 li $t2, 0 # start in column 0
dispCol:
 mul $t3, $t1, 6 # multiply rowindex* col_size
 add $t3, $t3, $t2 # add rowindex* col_size + colindex
 sll $t3, $t3, 2 # multiply by 4 (element size)
 add $t3, $t3, $t0 # add base_address to get addr(row,col)
 lw $t3, 0($t3) # load matrix(row,col)
 bgt $t3, 9999, disp1 # if 5 digits, display 1 space
 bgt $t3, 999, disp2 # if 4 digits, display 2 spaces
 bgt $t3, 99, disp3 # if 3 digits, display 3 spaces
 bgt $t3, 9, disp4 # if 2 digits, display 4 spaces
 j disp5 # else (1 digit) display 5 spaces
disp1:
 la $a0, blnks2
 j dispSpaces
disp2:
 la $a0, blnks3
 j dispSpaces
disp3:
 la $a0, blnks4
 j dispSpaces
disp4:
 la $a0, blnks5
 j dispSpaces
disp5:
 la $a0, blnks6
dispSpaces:
 li $v0, 4
 syscall
 move $a0, $t3 # display number
 li $v0, 1
 syscall
 la $a0, bar # display ending column bar
 li $v0, 4
 syscall
 add $t4, $t1, $t2 # add row + column to get total dice roll
 sll $t4, $t4, 2 # multiply by element size
 lw $t5, sums($t4) # load old sum value
 add $t5, $t5, $t3 # add count
 sw $t5, sums($t4) # save new sum value
 addi $t2, $t2, 1 # increment column
 blt $t2, 6, dispCol # repeat while col < 6
 la $a0, new_ln # display newline
 li $v0, 4
 syscall
 addi $t1, $t1, 1 # increment row
 blt $t1, 6, dispRow # repeat while row < 6
 la $a0, r_top # display bottom line
 li $v0, 4
 syscall
 la $a0, new_ln # display newline
 li $v0, 4
 syscall 
 la $a0, pctHdr # print percentage string
 li $v0, 4
 syscall
 l.s $f2, hundred # load 100 for calculations
 li $t0, 0 # start in first percentage
percLoop:
 la $a0, blnks5 # print initial spaces
 li $v0, 4
 syscall
 addi $a0, $t0, 2 # get roll number from index
 li $v0, 1 # print it
 syscall
 la $a0, colon # load colon string addres
 blt $t0, 8, printColon # if roll < 8, print colon
 la $a0, colon2 # else use colon2
printColon:
 li $v0, 4 # print the colon
 syscall
 la $a0, blnks1 # print a space
 li $v0, 4
 syscall
 sll $t1, $t0, 2 # multiply index by element size
 lw $t1, sums($t1) # load sums[i]
 mtc1 $t1, $f0 # load to coprocessor register
 cvt.s.w $f0, $f0 # convert to float
 div.s $f12, $f0, $f1 # divide num rolls/ total rolls
 mul.s $f12, $f12, $f2 # multiply by 100
 li $v0, 2 # print the float result
 syscall
 la $a0, new_ln # display newline
 li $v0, 4
 syscall
 addi $t0, $t0, 1 # increment index
 blt $t0, 11, percLoop # repeat while index < 11
 jr $ra
.end results
######################################################