validationassemblymipsmips32mars-simulator

Validating User Integer Input in MIPS Assembly


I have an assignment that requires me to make a basic calculator that can do the four basic operations (add, subtract, multiply, divide) on integers in MIPS assembly. Part of the assignment requires user input validation to make sure an integer as well as a correct operand is input by the user. I have the basic calculator and operand input validation done. I am wondering what the best, or a good way to accomplish the integer input validation would be.

Currently, I am using the syscall for reading in an integer. When the user inputs anything other than an integer, a zero is stored in the $v0 register (the return register for a syscall function). At first I simply used a branch if equal to zero command to branch to a subroutine which asks the user to input a valid integer and jumps back to the subroutine that reads and stores the integer. The only problem with this is, the user cannot input 0, which is a valid integer.

What is a good way I could go about doing this? Should I read the input in as a string, instead of an integer, and then parse the string to make sure every char's ASCII value corresponds with an integer ASCII value? Please let me know if more information is required. I cannot post the code because this is a currently active assignment in my class.


Solution

  • Given MARS/SPIM's limited set of toy "system calls", yes if you want to validate input you need to read a string and parse it into an integer yourself. total = total*10 + (c - '0') for base 10.

    And actually you'd want to check that each character is a valid digit, so maybe loop until you reach a non-digit, checking that c -= '0' is unsigned < 10, i.e. it's in the 0..9 range. That takes one add of -'0' (-32) and one sltiu + branch. See Verifying user input using syscall 8 in MIPS for actual code to validate input for a single decimal digit after reading it as a string.


    The $v0=5 read integer system call unfortunately has no other return value that indicates successful conversion or not like you'd get from C strtol or scanf. They could have designed the read-number calls to returns 0 or 1 in $v1 to indicate fail / success, but they didn't. (MARS copied SPIM's system calls and added some new ones, but not better versions of read integer.)

    For some insane reason, the read-string system call ($v0=8) apparently doesn't return the number of bytes read. It only stores a 0 terminator at the end of the input in the buffer. So you can't just calculate an end-pointer for a loop. But still, you can unambiguously loop over the bytes you read. So that's your starting point for knowing which bytes to look at in the first place.

    If you stop looping at the first non-digit, you can check that it was the terminating 0 byte.

    MARS does let you read() (v0=14) instead of fgets() from stdin, which will return a byte count.