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
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
######################################################
Similar Samples
Explore our diverse range of programming homework samples showcasing expertise across Java, Python, C++, and more. Each example demonstrates our proficiency in solving complex coding problems effectively. Whether you need assistance with algorithms, data structures, or web development projects, our samples illustrate our commitment to delivering high-quality solutions tailored to your academic needs.
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language