## LSU EE 4720 -- Computer Architecture -- Fall 2003
#
 ## Solution to Midterm Exam Problem 1
 #
 # Exam:http://www.ece.lsu.edu/ee4720/2003f/mt.pdf
 # Solution:http://www.ece.lsu.edu/ee4720/2003f/mt_sol.pdf

################################################################################
# Test Code
#
# Solution appears further below.

        .data
str:
        .space 100
fmt:    
        .asciiz "Converted 0x%/s0/x to \"%/a1/s\"\n"
numbers:
        .word 0x12345678
        .word 0x1a0c0
        .word 1
        .word 0

        .text
        .globl __start
__start:
        la $s1, numbers
        addi $v0, $0, 11
TLOOP:
        la $a1, str
        jal utoh
        lw $a0, 0($s1)
        lw $s0, 0($s1)
        la $a0, fmt
        syscall
        bne $s0, $0, TLOOP
        addi $s1, $s1, 4
        addi $v0, $0, 10
        syscall

################################################################################
## utoh: Convert unsigned integer to hexadecimal string.
##
        # $a0: Call Value: Unsigned integer to convert.
        # $a1: Call Value: Address of memory to write string to.
        #      Write converted string to this address.
        #      Sample written strings: "1F3", "1", "0"

        # [ ] String should not have leading zeros. (Good: "123", Bad "00123".)
        # [ ] Fill as many delay slots as possible.
        # [ ] Registers $a0-$a3 and $t0-$t7 can be modified.

        # The ASCII value of '0' is 48,  the ASCII value of 'A' is 65.

utoh: 
        # Number will be converted from LSD to MSD, and so the string
        # will be written backwards.

        ## Step 1
        #
        # Count number of leading zeros in hexadecimal representation
        # of $a0 (actually $a0 | 1 ) and use count to set $t3 to the
        # address of what will be the last character in the string.
        #

        lui $t1, 0xf000     # Mask used for extracting digits (starting at MSD).
        addi $t3, $a1, 7    # Init $t3 to address of last char of 8-digit number.
        ori $t5, $a0, 1     # OR in a 1 so that when a0 = 0 output is not "".

ILOOP:
        and $t0, $t5, $t1   # Extract a digit.
        slti $t4, $t0, 1    # Set $t4 to 1 if digit is zero.
        sub $t3, $t3, $t4   # Adjust end-of-string pointer.
        bne $t4, $0, ILOOP  # Loop if digit is zero.
        srl $t1, $t1, 4     # Shift the mask to the next digit.

        sb $0, 1($t3)       # Null-terminate the yet-to-be-written string.

        ## Step 2
        #
        # Convert the number to a string.
        #

LOOP:
        andi $t0, $a0, 0xf  # Extract LSD (least significant digit).
        slti $t1, $t0, 10   # Check if it will be 0-9 or A-F
        bne $t1, $0, SKIP
        srl $a0, $a0, 4     # Shift in next digit (for next iteration).
        addi $t0, $t0, 7    # Add 7 to digit if it is a letter.
SKIP:
        addi $t0, $t0, 48 # Add 48 to digit. (Seven also added if it's a letter.)
        sb $t0, 0($t3)      # Store the ASCII value in string.
        bne $t3, $a1, LOOP  # Loop if we have not written the first character.
        addi $t3, $t3, -1

EXIT:
        jr $ra
        nop