Converts numbers in range 0 through 15 into ASCII-coded character '0' through 'F' This is an assignment and i have implemented the function hexasc from the description above. To run this code I'm using MARS-simulator.
For the sake of understanding it better i would appreciate to see different approach.


  Write a small subroutine, that converts numbers in the range 0 through 15 into a printable ASCII-coded character: '0' through '9', or 'A' through 'F', depending on the number. For numbers not in the range 0 through 15, some bits will be ignored.
  
  The function must be called hexasc. 
  Parameter: One, in register $a0.
  The 4 least significant bits specify a number, from 0 through 15. All other bits in register $a0 can have any value and must be ignored. Return value: The 7 least significant bits in register $v0 must be an ASCII code as described below. All other bits must be zero when your function returns.
  
  Required action: The function must convert input values 0 through 9 into the ASCII codes for digits '0' through '9', respectively. Input values 10 through 15 must be converted to the ASCII codes for letters 'A' through 'F', respectively.


.text
main:
li      $a0,10      # change this to test different values

jal     hexasc      # call hexasc
nop             # delay slot filler (just in case)  

move    $a0,$v0     # copy return value to argument register

li      $v0,11      # syscall with v0 = 11 will print out
syscall         # one byte from a0 to the Run I/O window

stop:   j   stop            # stop after one run
nop             # delay slot filler (just in case)



hexasc:
andi    $a0,$a0,0xf     #only 4 least significant bits ignore other bits    
addi    $v0,$zero,0x30  #$v0 = 0x30 ('0')
addi    $t0,$zero,0x9   #t0 = 0x9

ble     $a0,$t0,L1      #branch if a0 &lt;= 0x9
nop
addi    $v0,$v0,0x7     #v0 = v0 +0x7

L1:
add     $v0,$a0,$v0     #v0 = V0 +a0
jr      $ra
nop
I see a few things that may help you improve your code.

Don't alter registers unless specified

The current code alters the $a0 register, which is appropriate to the problem, but the specification doesn't say that the register may be altered.  I'd suggest not altering passed in registers unless the specification says to.

Know your instruction set

The ble instruction can also work with a constant, so there's no real need to load a register with the value 9.  Also, it would be better to simply use a move instruction than the curious construct addi $t0,$zero,0x9.

Avoid nop instructions

I don't know of a reason that would require nop instructions where this code has them, so I'd recommend eliminating them.

Minimize register use

One of the most important things to keep track of in assembly language programming is register usage.  In this particular case, I'd suggest that there is no need to use more than a single register.  Here's how I'd do it:

hexasc:
andi $v0,$a0,0xf        # save only low 4 bits
addi $v0,$v0,0x30   # turn into ASCII
ble $v0,0x39,L2     # if it's &gt; ASCII '9'
addi $v0,$v0,7      #   add additional 7 for 'A'-'F'
L2:
jr $ra