3
\$\begingroup\$

I have written the following code for a programming assignment. I would appreciate some help to improve this code and see if it meets all the requirements and criteria. I would like to improve my loop and supporting continue function.

###############################
#String to int. 
###############################
######################################################################### 
##| The program obeys MIPS function calling convetions.
##| 
##| The program accepts two arguments for function stringToInt.
##| Argument A (testInput): address of null terminated string.
##| Argument B (base): An integer in the range of 2 and 16.
##| 
##| The program outputs an integer result converting the given
##| argument a into an integer.
##| If the second argument is not in the range of 2-16 the program 
##| returns error message and returns the value of zero. The same 
##| applies if the legal digits are not entered. 
##|
##| Legality of the input 
##| If the string has only the characters from '0' to '9' 
##| and from 'a' to 'f' and from 'A' to 'F' 
##| Input starting with '-' is accetped '+' is illegal. 
##| If the digits are not legal: 
##| The program prints out error message and returns value 0. 
##| 
##| 
##|_______________________________________________________________________#
#******************************Begin*************************************** 
.data
############### Test Case ###################
 stringInput: .asciiz "-1234" #String 
 base: .byte 16 #Base (2-16) 
##############################################
 #Prints out error message. 
 errorMessage: .asciiz "\nError. Please check input string."
.text 
###########################################################################
# Function: stringToInt
# Excepts two arguments string address and base. Loads base argument 
# into $a1 and char address into $t0. Converts string into ascii notation. 
# Checks the validity of base (between 2 and 16 incluseive) and if
# the input is negative. If negative convert it using twos complement. 
# If the base is not between 2-16 prints an error message return zero.
# Converts the string into integer. Terminates program at '\n' or '0円'. 
stringToInt: 
 la $t0, stringInput #current char address in t0
 li $t2, 0 #decimal equivalent intialized to 0
 li $t4, 1 #power 
 lb $a1, base #load base into register a1
 bgt $a1, 16, invalid #checks if base is valid
 lb $s6, base #loads base into register s6 
 addi $s6, $s6, 48 # converts s6 to ascii notation
 lb $s0, ($t0) 
 la $t5, stringInput
 beq $s0, '-', negSet #checks first element of string to see if it is a minus sign
 j check #jump to check
#_________________________________________________________________________#
###########################################################################
# Checks if the nubmer is negative. 
negSet:
 addi $s7, $zero, 1 #s1 will store a value to check if no is negative 
 addi $t0, $t0, 1
 addi $t5, $t5, 1
#_________________________________________________________________________#
########################################################################### 
#Go till end of end of input
check:
 lb $t1, ($t0)
 beq $t1, '\n', endCheck
 beq $t1, '0円', endCheck
 add $t0, $t0, 1
 b check
endCheck:
#_________________________________________________________________________#
###########################################################################
# Go from last char to first, decrementing address. Compare from highest
# ascii value. If less than start address jummp to countinue4. Else invalid 
loop:
 sub $t0, $t0, 1
 blt $t0, $t5 , valid #if less than start address stop
 lb $t1, ($t0)
 bgt $s6, 57, continue3 #compare from highest ascii value
 bge $t1, $s6, invalid #branch to invaldi if $t1 >= $s6
 j continue4 #jump to continue 4
# exit point if base is greater than 10
continue3:
# makes sure only needed values are used 
continue4: 
 bge $t1, 'g', invalid 
 bge $t1, 'a', lower
 bge $t1, 'G', invalid
 bge $t1, 'A', upper
 bge $t1, '9', invalid
 bge $t1 , '0', digit
#print error message and exit. 
invalid:
 li $v0,1
 li $a0,0
 syscall
 li $v0, 4
 la $a0, errorMessage 
 syscall
 b exit
#Peforms validity checks. 
#Check if the vlaue is negative. (Using twos complement) 
valid:
 addi $t1, $zero, 1
 sll $t1, $t1, 31
 and $s1, $t2, $t1 
 bne $s1, $zero, bignegative
 bne $s7, $zero, twosComplement # checkes the s7 register to see if our value is negative
# Return point after converting to negative number if a minus sign 
# was detected. Print and exit. 
continue2: 
 li $v0, 1 # Print content of t2
 move $a0, $t2
 syscall
 b exit 
# manipulates the digit to convert and checks validity. 
digit:
 bgt $t1, '9', invalid
 sub $t3, $t1, '0' #get numeric digit value
 mul $t3, $t3, $t4 #mulitply by the current power 
 add $t2, $t2, $t3
 mul $t4, $t4, $a1 #next power 
 j loop #jump back to loop 
#get numeric digit value 
lower:
 bgt $t1, 'f', invalid 
 sub $t3, $t1, 'a'
 add $t3, $t3, 10
 mul $t3, $t3, $t4 #mulitply by the current power
 add $t2, $t2, $t3
 mul $t4, $t4, $a1 #next power 
 b loop #branch to loop 
#get numeric digit value 
upper:
 bgt $t1, 'F', invalid
 sub $t3, $t1, 'A'
 add $t3, $t3, 10
 mul $t3, $t3, $t4 #mulitply by the current power 
 add $t2, $t2, $t3 #add to decimal
 mul $t4, $t4, $a1 #next power 
 b loop #branch to loop 
bignegative:
 li $t7, 10 # load value 10 into register t7
 divu $t2, $t7
 mflo $t1 # move value of LO register into $t1
 mfhi $t7 # move value of HI register into $t7
 #Print t1
 add $a0, $t1, $zero
 li $v0, 1
 syscall
 # printt7
 add $a0, $t7, $zero
 li $v0, 1
 syscall
#Ends the program and exit. 
#tell the system this is the end of stringToInt 
exit: 
 li $v0, 10
 syscall
#Perform the twos complement by subracting zero. To convert 
#negative input. 
twosComplement:
 sub $t2, $zero, $t2 # convert number to negative
 j continue2 #jump to continue2 
#_________________________________________________________________________#
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Dec 13, 2017 at 1:10
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I'm not familiar with MIPS, but I can make some observations.

  • General impressions: well presented code with appropriate level of comments.

  • You do seem confused by the character coding:

    # Converts string into ascii notation
    

    That's the other way around - ASCII is the encoding of the characters into bytes, so what you're doing is requiring that the input string uses the ASCII encoding.

  • Does MIPS not have a bne instruction? This code always jumps:

     beq $s0, '-', negSet #checks first element of string to see if it is a minus sign
     j check #jump to check <-- OVERCOMMENT
    # Checks if the number is negative. 
    negSet:
     addi $s7, $zero, 1 #s1 will store a value to check if no is negative 
     addi $t0, $t0, 1
     addi $t5, $t5, 1
    check:
    

    By inverting the initial test, we can have one case that doesn't branch:

     bne $s0, '-', check #checks first element of string to see if it is a minus sign
    # Number is negative. 
    negSet:
     addi $s7, $zero, 1
     addi $t0, $t0, 1
     addi $t5, $t5, 1
    check:
    
  • Here's a no-op jump (also with a comment that adds nothing to the code):

     j continue4 #jump to continue 4
    continue3:
    continue4: 
    
  • The tests here assume ASCII ordering:

    bge $t1, 'g', invalid 
    bge $t1, 'a', lower
    bge $t1, 'G', invalid
    bge $t1, 'A', upper
    bge $t1, '9', invalid
    bge $t1 , '0', digit
    

    That's not necessarily a problem in itself, but it does warrant a comment, so that if it has to be adapted to other encodings where 0..9, A..F, a..f, are in different orders (or, potentially, discontiguous), then it would be easier to find the part to be modified.

    I'm concerned that you may be counting 9 as an invalid digit in the above - has this code actually been tested with limit values? It would be clearer to write the tests in consistent form (0x9AxFaxf) rather than mixing 9 with < G|g.

    An alternative, flexible approach might be to define a table mapping character codes to their digit values, with a suitable marker for invalid (anything over 16 will work for us; FFh is a good choice). This trades a small amount of code for a (probably) faster lookup; it allows the table to be chosen at runtime to support different encodings. (I'm not necessarily recommending this, but it improves your learning experience if you at least consider how to do it, and what the costs and benefits would be.)

  • It shouldn't be necessary to perform separate validation and conversion steps. We can validate as we go, and jump out of the conversion at the point that we reach an invalid character for the base.

  • I don't see any check for overflow. What if the input number is too large to be represented?

  • Tests - you haven't presented any tests. I'd like to see tests confirming:

    • reject base 1.
    • reject base 17.
    • In any valid base, reject "" and "-".
    • In base 2, reject "2", "A" and "a", but accept "00" and "11".
    • In base 10, reject "A" and "a", but accept "00" and "99".
    • In base 11, reject "B" and "b", but accept "00", "99" and "0a".
    • In base 16, reject "G" and "g", but accept "09" and "af".
    • Test "-0", "-1" and a large negative value convert correctly.
    • Some additional tests of - other than as first character.
answered Dec 13, 2017 at 9:31
\$\endgroup\$
1
  • \$\begingroup\$ Dear Toby, Thank you for your good detailed analysis of my code. I am a beginner in MIPS assembly language. Yes, I have made some mistakes thanks for pointing them out. I will post some of my results. Also, another thing I noticed was that I did not follow MIPS calling conventions which I need to fix as well. \$\endgroup\$ Commented Dec 13, 2017 at 20:24

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.