## LSU EE 4720 Computer Architecture Spring 2021
#
#  Classroom example for review of MIPS:
#    Convert an unsigned integer to an ASCII hexadecimal string.
#
#  There are two routines in this file. The routine to convert an
#  unsigned integer to a hex string is named "itos". The routine named
#  "__start" calls itos several times and displays the results.
#
#  For a review of MIPS, see https://www.ece.lsu.edu/ee4720/2020/lmips.s.html
#  Details on MIPS can be found on this page (along with other ISAs):
#    https://www.ece.lsu.edu/ee4720/reference.html

###############################################################################
#
 ## Unsigned Integer to Hexadecimal String
#

itos:
        ## Register Usage
        #
        # CALL VALUES:
        #  $a0: Unsigned integer to convert
        #  $a1: Address of storage.
        #       Initialized to null-terminated string of blanks.
        #  $a2: Length of storage.
        #
        # RETURN:
        #       There is no return register value ..
        #       .. instead write storage at $a1 with hex representation of $a0.
        #
        # NOTE: Registers $a0-$a4 and $t0-$t7 can be modified.
        # NOTE: 'a' = 97, 'z' = 122,  'a' - 'A' = 32
        # NOTE: '0' = 48 = 0x30


        # addi $t0, $0, 122
        # sb $t0, 0($a1)
        # addi $t0, $0, 101
        # sb $t0, 1($a1)
        # sb $t0, 2($a1)

        addi $t9, $0, 10

LOOP:
        andi $t0, $a0, 0xf
        # slti $t1, $t0, 10
        # bne $t1, $0, ANUMBER
        blt $t0, $t9, ANUMBER
        addi $t0, $t0, 48
        addi $t0, $t0, 39
ANUMBER:
        sb $t0, 8($a1)

        srl $a0, $a0, 4
        bne $a0, $0, LOOP
        addi $a1, $a1, -1


        jr $ra
        nop


##############################################################################
#
 ## Test Code
#
#  The code below calls "itos", the routine that converts an unsigned
#  integer to hexadecimal. It calls itos several times, after each
#  call it displaces the results.

        .data
msg:
        .asciiz "The value of %/s4/5d = 0x%/s4/x is %/a1/s\n"
str:
        .align 4
        .space 12               # Storage for string.
values:                         # Table of test inputs.
        .word 1, 9, 10          # First entries in table of test inputs.
        .word 15, 16, 17
        .word 0x12321
        .word 0x12345
        .word 1234
        .word 0x1234
        .word 0xf00d
        .word -1


        .text
        .globl __start
__start:
        la $s2, values          # Address of table of test inputs.
        addi $s3, $0, -1;       # Value that marks end of table.
MLOOP:
        lw $a0, 0($s2)          # Load a test input from the table.
        la $a1, str             # Set $a1 to address of storage for string.
        lui $t0, 0x2020         # Prepare an initial value for string.
        ori $t0, $t0, 0x2020    # t0 will contain four blanks.
        sw $t0, 0($a1)          # Write string with initial value (blanks).
        sw $t0, 4($a1)
        sw $t0, 8($a1)
        sb $0, 11($a1)
        jal itos
        addi $a2, $0, 10        # Set length of string.
        lw $s4, 0($s2)          # Load test input again.
        la $a1, str             # Address of string.
        la $a0, msg             # Address of message (printf-like format str)
        addi $v0, $0, 11        # Code indicating we want to run printf.
        syscall                 # Make a system call to do printf.
        addi $s2, $s2, 4        # Advance to next entry in table.
        bne $s4, $s3 MLOOP      # Continue if we are not at end of table.
        li $v0, 10              # Exit system call. (Not used if branch taken.)
        syscall
        nop