Created
November 21, 2023 10:42
-
-
Save ppdms/7409594039c52f5e8fa3efe84042a7a9 to your computer and use it in GitHub Desktop.
Calculate binomial coefficient in MIPS32 assembly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .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