Skip to content

Instantly share code, notes, and snippets.

@ppdms
Created November 21, 2023 10:42
Show Gist options
  • Select an option

  • Save ppdms/7409594039c52f5e8fa3efe84042a7a9 to your computer and use it in GitHub Desktop.

Select an option

Save ppdms/7409594039c52f5e8fa3efe84042a7a9 to your computer and use it in GitHub Desktop.
Calculate binomial coefficient in MIPS32 assembly
.text
.globl __start
_start:
la $a0, pn
li $v0, 4
syscall # print prompt for n
la $v0, 5
syscall # read n into $v0
move $t0, $v0 # read n into $t0
# we can use temp. registers in the entirety of this scope
# without the danger of side effects changing their contents
la $a0, pk
li $v0, 4
syscall # print promt for k
la $v0, 5
syscall # read k into $v0
move $t1, $v0 # read k into $t1
blt $t0, $t1, err # assert n >= k
blt $t1, $zero, err # assert k >=0 (and thus n>=0)
li $t2, 13 # set $t2 to 13, max(k) + 1
bge $t1, $t2, bnd # if k is greater or equal to max(k) + 1, error
la $t2, arr # array address
li $t3, 4 # word length
mul $t3, $t1, $t3 # store offset in $t3 (k * 4)
add $t2, $t2, $t3 # calculate pointer to arr[k] (&arr + k*4)
lw $t2, ($t2) # load arr[k] to $t2
blt $t2, $t0, bnd # if n is greater than arr[k], error
li $t2, 1 # set $t2 to 1
move $t4, $t0 # store n in $t4 (for printing later)
move $t5, $t1 # store k in $t5 (for printing later)
sub $t3, $t0, $t1 # set $t3 to n-k
blt $zero, $t1, denom # don't have to compute k! if k == 0
li $t1, 1 # if k == 0, make result 1
j res # show result in this case
denom:
mul $t2, $t1, $t2 # multiply denominator (in $t2) by next factor (in $t1)
addiu $t1, $t1, -1 # produce next factor ($t1) by -= 1
blt $zero, $t1, denom # if next factor > 1, continue the loop
li $t1, 1 # set numerator (in $t1) to 1
num:
mul $t1, $t0, $t1 # multiply numerator (in $t1) by next factor (in $t0)
addiu $t0, $t0, -1 # produce next factor ($t0) by -= 1
blt $t3, $t0, num # if next factor > n-k, continue the loop
res:
div $t1, $t1, $t2 # calculate the fraction C(n, k)
la $a0, o0
li $v0, 4
syscall # print "C("
move $a0, $t4
li $v0, 1
syscall # print n
la $a0, o1
li $v0, 4
syscall # print " ,"
move $a0, $t5
li $v0, 1
syscall # print k
la $a0, o2
li $v0, 4
syscall # print ") = "
move $a0, $t1
li $v0, 1
syscall # print result
addi $a0, $0, 0xA # ascii for CR
li $v0, 11
syscall # print newline
li $v0, 10
syscall # exit
err:
la $a0, pe
li $v0, 4
syscall # print error message
li $v0, 10
syscall # exit
bnd:
la $a0, warn
li $v0, 4
syscall # print error message
li $v0, 10
syscall # exit
.data
pn: .asciiz "Enter number of objects in the set (n): "
pk: .asciiz "Enter number to be chosen (k): "
pe: .asciiz "Please enter n >= k >= 0"
o0: .asciiz "C("
o1: .asciiz ", "
o2: .asciiz ") = "
arr: .word 2147483647, 2147483647, 46341, 1291, 216, 75, 38, 24, 18, 15, 13, 12, 12
warn: .asciiz "\nThe values you provided exceeded the limits of this procedure.\nFor all calculations, k must be between 0 and 12. Furthermore,\nfor a given value of k (on the left column) n must not exceed\nthe value given on the right of the same row, for this table:\n\nk n\n0 2147483647\n1 2147483647\n2 46341\n3 1291\n4 216\n5 75\n6 38\n7 24\n8 18\n9 15\n10 13\n11 12\n12 12\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment