## long mult -- multiplies two 32-bit integers
## Register usage:
## This program accomplishes the same thing as mul or mult
## But this shows the inner workings.
## $t1 mask
## $t2 multiplier (and right_hand_sum).
## $t3 left_hand_sum.
## $t4 multiplicand.
## $t5 - clear.
## $t6 - rightmost bit of left_hand_sum.
## $t7 - rightmost bit of right_hand_sum.
## $t8 - counter
## $v0 syscall parameter / return values.
## $a0 syscall parameters.
## $a1 syscall parameters.
.text
.globl __start
__start:
## read the two integers
li $v0, 5 # load multiplicand.
syscall
move $t4, $v0
li $v0, 5 # load multiplier.
syscall
move $t2, $v0
lw $t1, mask
lw $t5, clear
li $t8, 32
continue:
beqz $t8, end
and $t7, $t1, $t2
beqz $t7, shift
add $t3, $t3, $t4
shift: and $t6, $t3, $t1 # store rightmost bit of l_sum in $t6
and $t2, $t2, $t5 # clear rightmost bit of r_sum
or $t2, $t2, $t6 # move stored right bit of l_sum to rightmost position of r_sum
ror $t2, $t2, 1 # rotate r_sum
srl $t3, $t3, 1 # shift l_sum right
# Use sra for twos complement numbers.
# Note: This program has a slight bug that can easily be fixed.
# If a carry occurred on the add instruction 4 lines above
# whether unsigned or two's complement,
# then you always bring in a 1 from the left into $t3
# The easiest way to check for a carry -- (i.e. unsigned overflow) avoids masks!
# bltu $t3, $t4 checks whether $t3 + $t4 (i.e., add $t3, $t3, $t4) threw a carry. For example:
# Consider 4-bit numbers: $t3 = 1011 and $t4 = 0111, When we add these, $t3 becomes 0010, and the addition throws a carry
# Since this 0010 is less than 0111, we know that a carry occurred.
# Now once you can check for a carry, if the carry exists, we must overwrite 1 into the leftmost bit of $t3
# This is done using ori $t3 , $t3, 0x8000000
addiu $t8, $t8, -1
b continue
end: sw $t2, r_sum
sw $t3, l_sum
li $v0, 10
syscall
.data
r_sum: .word 0
l_sum: .word 0
mask: .word 0x00000001
clear: .word 0xFFFFFFFE