## 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