Hexadecimal Conversion

For this assignment you will write MAL subprograms for converting a string of hexadecimal characters to an integer. You will first write a subprogram hexVal that converts hexadecimal digit characters to their MIPS long value. Then you will add the subprogram toInt that uses hexVal to convert strings of hexadecimal digits to MIPS long values. Test software will be provided.

In this program you will get experience using branches for more complex control structures and using the jalr instruction for subprogram calls and the jr instruction for subprogram returns.

Test Software

The test software is provided in the file conversion.zip. This unzips to create a folder named "conversion". It contains the following files:

If you have configured Mars settings correctly you should be able to open any one of these files in Mars, then assemble and run the program. It won't, of course, give correct results until you have implemented the two subprograms.

The hexVal Subprogram

The algorithm for hexVal is described by the following C code:

  /** hexVal(ch) returns the hexadecimal value of the character ch, or
   * -1 if it cannot be a hexadecimal digit.
   */
  int hexVal(char ch) {
    if ((ch1 >= '0') && (ch <= '9')) {
      return ch - '0';
    }
    if (ch >= 'a') and (ch <= 'f') {
      return ch - 'a' + 10;
    }
    if (ch >= 'A') and (ch <= 'F') {
      return ch - 'A' + 10;
    }
    return -1;
  }

If you implement this algorithm as shown you should not need to use any $t registers (do not use $s registers in any case). This simplifies the coding of the toInt subprogram.

Note that in MAL you can do a subtraction that mixes characters and integers. MAL treats a character literal as if it was the integer ASCII code for the character.

hexVal Tests

The test software tests toInt with characters from the string:

testString:
    .asciiz "/059:@ACFG`acfg"

The characters in this test string should reveal any problems with your toInt implementation.

The toInt Subprogram

toInt converts a null-terminated string of hexadecimal digits to a word size integer. It should have an input parameter which is the address of the string to be converted. It should also have two output parameters. The first is a word representing the integer value of the string, interpreted as a hexadecimal number. The second is a boolean success parameter. It should be set to false (0) if any non-hexadecimal characters are encountered in the string or if the string is empty. Otherwise, the success parameter should be set to true (nonzero).

Your toInt subprogram should call the hexVal subprogram for conversion of the individual hexadecimal digits (characters) to integer values. It should use a repeated multiplication algorithm for conversion.

Using the Run-Time Stack

Since the toInt subprogram calls another subprogram, hexVal, you cannot use the simple subprogram call protocol because you need to push the return address for toInt onto the run-time stack before calling hexVal and pop it after the call. Both of the test subprograms illustrate how this is done.

If your hexVal subprogram uses $t registers then the toInt subprogram will also need to save them on the run-time stack before calling toInt and restore them after toInt returns.

toInt Tests

The test software provides the following test strings for toInt:

test1:
    .asciiz "a"
test2:
    .asciiz "ff"
test3:
    .asciiz "43E"
test4:
    .asciiz "C840"
test5:
    .asciiz "7FfFfFfF"
test6:
    .asciiz "7FfFgFfF"
test7:
    .asciiz ""

For the last two test strings the success return value should be false — the strings are not valid hexadecimal digit strings.

What to Turn in

Turn in both a copy of your program and a Mars session record showing a session assembling and running the provided test software with your hexVal and toInt subprograms.

Your TA may also ask you to demonstrate your program in lab.

References