Converting Strings to 32-Bit Integers using Booth Algorithm

Implementing Booth’s multiplication algorithm in MIPS assembly homework help

Solution .data prompt_mul1: .asciiz "Multiplicand?: " prompt_mul2: .asciiz "Multiplier?: " error_msg1: .asciiz "Invalid multiplicand. Please try again\n" error_msg2: .asciiz "Invalid multiplier. Please try again\n" out1_msg: .asciiz "\n " out2_msg: .asciiz "\nX " line: .asciiz "\n --------------------------------" num_string: .space 12 #place to save numerical strings .text .globl main main: read_mul1: # Prompt for multiplicand li $v0, 4 # syscall to print a string la $a0, prompt_mul1 # load prompt for multiplicand syscall # print the prompt # Read first number as a string li $v0, 8 # syscall number to read string la $a0, num_string # place to save read string li $a1,12 # 12 chars maximum syscall # read the string #Convert first number to an integer la $a0, num_string # load pointer to read string jal convert_to_int # convert string to integer move $s0, $v0 # save converted number in s0 beq $v1, $0, read_mul2 # if no errors read next number # if error print an error message la $a0, error_msg1 # load address of error message li $v0, 4 # syscall number to print a string syscall # print error string j read_mul1 # read multiplicand again read_mul2: # Prompt for multiplier li $v0, 4 # syscall to print a string la $a0, prompt_mul1 # load prompt for multiplier syscall # print the prompt # Read second number as a string li $v0, 8 # syscall number to read string la $a0, num_string # place to save read string li $a1,12 # 12 chars maximum syscall # read the string #Convert second number to an integer la $a0, num_string # load pointer to read string jal convert_to_int # convert string to integer move $s1, $v0 # save converted number in s1 beq $v1, $0, print_muls # if no errors, start printing inputs # if error print an error message la $a0, error_msg2 # load address of error message li $v0, 4 # syscall number to print a string syscall # print error string j read_mul2 # read multiplier again print_muls: # print spaces la $a0, out1_msg # load address of message li $v0, 4 # syscall number to print a string syscall # print string # print multiplicand move $a0, $s0 # load multiplicand number li $a1, 32 # print in 32 bits jal print_bin # print number as 32 bit binary # print multiplication X la $a0, out2_msg # load address of message li $v0, 4 # syscall number to print a string syscall # print string # print multiplier move $a0, $s1 # load multiplier number li $a1, 32 # print in 32 bits jal print_bin # print number as 32 bit binary # print division line la $a0, line # load address of error message li $v0, 4 # syscall number to print a string syscall # print string # start Booth's algorithm # M = S0 # Q = s1 li $s2, 0 # initialize AC = 0 li $s3, 0 # initialize Q-1 = 0 li $s4, 32 # set counter to n=32 bits long booth_loop: #print current registers # print spaces la $a0, out1_msg # load address of message li $v0, 4 # syscall number to print a string syscall # print string # print upper register AC move $a0, $s2 # load number li $a1, 32 # print in 32 bits jal print_bin # print number as 32 bit binary # print lower register Q move $a0, $s1 # load number li $a1, 32 # print in 32 bits jal print_bin # print number as 32 bit binary andi $t0, $s1, 1 # load LSB of multiplier Q beq $t0, $s3, shift # if Q0 and Q-1 are equal, go to shift bne $t0, $0, subtract # if Q0 = 1 and Q-1 is 0, subtract add: # else, Q0 = 0 and Q-1 is 1, add add $s2, $s2, $s0 # add AC + M j shift subtract: sub $s2, $s2, $s0 # subtract AC - M shift: andi $t1, $s2, 1 # get LSB of AC sra $s2, $s2, 1 # shift AC to the right srl $s1, $s1,1 # shift Q to the right move $s3, $t0 # move Q0 to Q-1 sll $t1, $t1, 31 # put bit shifted out of AC in Q or $s1, $s1, $t1 addi $s4, $s4, -1 # decrement counter bne $s4, $0, booth_loop # repeat while counter is not zero # print last result # print division line la $a0, line # load address of error message li $v0, 4 # syscall number to print a string syscall # print string # print spaces la $a0, out1_msg # load address of message li $v0, 4 # syscall number to print a string syscall # print string # print upper register AC move $a0, $s2 # load number li $a1, 32 # print in 32 bits jal print_bin # print number as 32 bit binary # print lower register Q move $a0, $s1 # load number li $a1, 32 # print in 32 bits jal print_bin # print number as 32 bit binary #Exit the program li $v0, 10 # syscall number to exit program syscall # exit the program # Function to convert a string to an integer, # the string pointer must be given in a0, # returns the result in v0, v1 is 1 if there was an error convert_to_int: li $v1, 0 # start without error flag li $t0, 45 # load sign character lb $t1, 0($a0) # load first character from string li $t2, 0 # load 0 to use as flag to indicate if number is positive bne $t1, $t0, positive # if not a sign, it's positive, start conversion li $t2, 1 # save 1 to indicate is negative addi $a0, $a0, 1 # advance to next char in string positive: lb $t1, 0($a0) # load character from numeric string beq $t1, $0, convert_error # if string is empty, return eror beq $t1, 10, convert_error # if string is empty, return eror li $v0, 0 # start with converted number in zero li $t3, 10 # load 10 to make multiplications convert_loop: lb $t1, 0($a0) # load character from numeric string beq $t1, $0, convert_end # if it's the ending null char, terminate conversion beq $t1, 10, convert_end # if it's the ending null char, terminate conversion #validate char slti $t0, $t1, 48 # compare with '0' char, set t0 to 1 if lower than 0 bne $t0, $0, convert_error # if char < '0' is not a valid digit, go to error li $t4, 57 # load ascii code for '9' char beq $t1, $t4, valid_digit # if char is '9', it's a valid digit, continue conversion slt $t0, $t1, $t4 # compare with '9' char, set t0 to 1 if lower than '9' beq $t0, $0, convert_error # if char > '9' is not a valid digit, go to error valid_digit: addi $t1, $t1, -48 # subtract ascii '0' to convert char to integer mult $v0, $t3 # multiply old conversion by 10 mflo $v0 # load result in v0 add $v0, $v0, $t1 # add digit to conversion addi $a0, $a0, 1 # advance to next char in string j convert_loop # repeat to convert next char convert_error: li $v1, 1 # set v1 to 1 to indicate error li $v0, 0 # clear conversion li $t2, 0 # clear sign convert_end: beq $t2, $0, convert_ret # if the number was positive, return it xori $v0, $v0, -1 # else, it's negative, convert to negative using two's complement, first invert addi $v0, $v0, 1 # then add 1 convert_ret: jr $ra # return to caller with conversion in $v0, error in $v1 # Function to print the number given in a0 as a binary number in the number of bits # given in a1 print_bin: move $t2, $a0 # save a0 in t2 print_bin_loop: slti $a0, $t2, 0 # if negative bit is set, put 1 in t0 addi $a0, $a0, 48 # convert bit to ascii adding '0' li $v0, 11 # syscall number to print a character syscall # print bit digit sll $t2, $t2, 1 # move next bit to sign bit addi $a1, $a1, -1 # decrement number of bits to print bne $a1, $0, print_bin_loop # repeat while the number is not zero jr $ra # return to caller