Guest User

Untitled

a guest
Jul 15th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.43 KB | None | 0 0
  1. # sprintf.s
  2. #
  3. # Formats a string into a string, returns it's length.
  4. # Expects: $a0 - address of resulting string
  5. # $a1 - string format
  6. # $a2 - first element
  7. # $a3 - second element
  8. # Returns: $v0 - length of the string
  9. #
  10.  
  11. sprintf:
  12. li $t1, 0 #current item (0 starting)
  13. add $t7, $a0, $0 #keep track of where the string started
  14. sfloop:
  15. lbu $t0, ($a1) #load char
  16. beq $t0, '%', sfschar #check for % char
  17. sb $t0, ($a0) #copy char
  18. beq $t0, 0, sfendstring #null terminates
  19. addi $a1, $a1, 1 #increment source pointer
  20. addi $a0, $a0, 1 #increment dest pointer
  21. j sfloop
  22. sfschar:
  23. addi $a1, $a1, 1 #increment source pointer
  24. lbu $t0, ($a1) #load char after '%'
  25. bne $t1, $0, sfsca #check if we're on the first item
  26. move $t2, $a2 #load the first item into $t2
  27. addi $t1, $t1, 1 #set to look for next item next time
  28. j sfscr #skip the next thing
  29. sfsca:
  30. move $t2, $a3 #else load the second item into $t2
  31. sfscr:
  32. beq $t0, 'd', sfdec #format integer->decimal
  33. beq $t0, 'x', sfhex #format integer->hex
  34. beq $t0, 's', sfstring #format string->string
  35. beq $t0, 'c', sfchar #format char->string
  36. sb $t0, ($a0) #must be a % (or unrecognized) just copy.
  37. addi $t1, $t1, -1 #false alarm about item loading, go back one space.
  38. addi $a1, $a1, 1 #increment source pointer
  39. addi $a0, $a0, 1 #increment dest pointer
  40. j sfloop
  41. sfdec:
  42. add $t4, $t2, $0 #we're going to be screwing with this one.
  43. li $t5, 0 #place to count how many digits are needed.
  44. sfdsizeloop:
  45. div $t4, $t4, 10 #drop a digit from the number
  46. addi $t5, $t5, 1 #increment the digit counter
  47. blt $t4, 1, sfdslbreak #stop the loop if there's no digits left.
  48. j sfdsizeloop
  49. sfdslbreak:
  50. add $t5, $t5, $a0 #convert $t5 to the dest pointer for the backwards print loop
  51. add $t6, $a0, $0 #save the original dest pointer so we can tell when we've reached it.
  52. add $a0, $t5, $0 #set the global dest pointer to where the end will be. ($t5==$a0)
  53. sfdbackwardsprintloop:
  54. rem $t3, $t2, 10 #grab digit
  55. addi $t3, $t3, '0' #convert it to char
  56. sb $t3, ($t5) #store least digit first
  57. addi $t5, $t5, -1 #decrement temporary dest pointer
  58. div $t2, $t2, 10 #actually divide int by 10 now that we've grabbed a digit.
  59. blt $t5, $t6, sfdbplbreak #break the loop if we're out of space (should be done writing msd)
  60. j sfdbackwardsprintloop #else continue printing backwards.
  61. sfdbplbreak:
  62. addi $a1, $a1, 1 #increment the source pointer.
  63. addi $a0, $a0, 1 #increment the dest pointer.
  64. j sfloop #return to normal operation.
  65. sfhex:
  66. add $t4, $t2, $0 #we're going to be screwing with this one.
  67. li $t5, 0 #place to count how many digits are needed.
  68. sfhsizeloop:
  69. div $t4, $t4, 16 #drop a digit from the number
  70. addi $t5, $t5, 1 #increment the digit counter
  71. blt $t4, 1, sfhslbreak #stop the loop if there's no digits left.
  72. j sfhsizeloop
  73. sfhslbreak:
  74. add $t5, $t5, $a0 #convert $t5 to the dest pointer for the backwards print loop
  75. add $t6, $a0, $0 #save the original dest pointer so we can tell when we've reached it.
  76. add $a0, $t5, $0 #set the global dest pointer to where the end will be. ($t5==$a0)
  77. sfhbackwardsprintloop:
  78. rem $t3, $t2, 16 #grab digit
  79. addi $t3, $t3, '0' #convert to char (0-9)
  80. ble $t3, '9', sfhbplnumeral #if the digit <= 9, we don't need to boost it to ascii letter range.
  81. addi $t3, $t3, 7 #this should change ':' to 'A' (value 10)
  82. sfhbplnumeral:
  83. sb $t3, ($t5) #store least digit first
  84. addi $t5, $t5, -1 #decrement temporary dest pointer
  85. div $t2, $t2, 16 #actually divide int by 10 now that we've grabbed a digit.
  86. blt $t5, $t6, sfhbplbreak #break the loop if we're out of space (should be done writing msd)
  87. j sfhbackwardsprintloop #else continue printing backwards.
  88. sfhbplbreak:
  89. addi $a1, $a1, 1 #increment the source pointer.
  90. addi $a0, $a0, 1 #increment the dest pointer.
  91. j sfloop #return to normal operation.
  92. sfstring:
  93. lbu $t3, ($t2) #load character from string
  94. beqz $t3, sfstrnullterm #item string has terminated, return to normal operation.
  95. sb $t3, ($a0) #store character in result string
  96. addi $a0, $a0, 1 #increment dest pointer
  97. addi $t2, $t2, 1 #increment item source pointer
  98. j sfstring
  99. sfstrnullterm:
  100. addi $a1, $a1, 1 #increment the source pointer
  101. j sfloop
  102. sfchar:
  103. sb $t2, ($a0) #print char into string
  104. addi $a0, $a0, 1 #increment dest pointer
  105. addi $a1, $a1, 1 #increment source pointer
  106. j sfloop #return to normal operation.
  107. sfendstring:
  108. sub $v0, $a0, $t7 #string length = end address - start address
  109. jr $ra #kthxbye (sorry for trashing your temps. I use them alot)
Add Comment
Please, Sign In to add comment