Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # sprintf.s
- #
- # Formats a string into a string, returns it's length.
- # Expects: $a0 - address of resulting string
- # $a1 - string format
- # $a2 - first element
- # $a3 - second element
- # Returns: $v0 - length of the string
- #
- sprintf:
- li $t1, 0 #current item (0 starting)
- add $t7, $a0, $0 #keep track of where the string started
- sfloop:
- lbu $t0, ($a1) #load char
- beq $t0, '%', sfschar #check for % char
- sb $t0, ($a0) #copy char
- beq $t0, 0, sfendstring #null terminates
- addi $a1, $a1, 1 #increment source pointer
- addi $a0, $a0, 1 #increment dest pointer
- j sfloop
- sfschar:
- addi $a1, $a1, 1 #increment source pointer
- lbu $t0, ($a1) #load char after '%'
- bne $t1, $0, sfsca #check if we're on the first item
- move $t2, $a2 #load the first item into $t2
- addi $t1, $t1, 1 #set to look for next item next time
- j sfscr #skip the next thing
- sfsca:
- move $t2, $a3 #else load the second item into $t2
- sfscr:
- beq $t0, 'd', sfdec #format integer->decimal
- beq $t0, 'x', sfhex #format integer->hex
- beq $t0, 's', sfstring #format string->string
- beq $t0, 'c', sfchar #format char->string
- sb $t0, ($a0) #must be a % (or unrecognized) just copy.
- addi $t1, $t1, -1 #false alarm about item loading, go back one space.
- addi $a1, $a1, 1 #increment source pointer
- addi $a0, $a0, 1 #increment dest pointer
- j sfloop
- sfdec:
- add $t4, $t2, $0 #we're going to be screwing with this one.
- li $t5, 0 #place to count how many digits are needed.
- sfdsizeloop:
- div $t4, $t4, 10 #drop a digit from the number
- addi $t5, $t5, 1 #increment the digit counter
- blt $t4, 1, sfdslbreak #stop the loop if there's no digits left.
- j sfdsizeloop
- sfdslbreak:
- add $t5, $t5, $a0 #convert $t5 to the dest pointer for the backwards print loop
- add $t6, $a0, $0 #save the original dest pointer so we can tell when we've reached it.
- add $a0, $t5, $0 #set the global dest pointer to where the end will be. ($t5==$a0)
- sfdbackwardsprintloop:
- rem $t3, $t2, 10 #grab digit
- addi $t3, $t3, '0' #convert it to char
- sb $t3, ($t5) #store least digit first
- addi $t5, $t5, -1 #decrement temporary dest pointer
- div $t2, $t2, 10 #actually divide int by 10 now that we've grabbed a digit.
- blt $t5, $t6, sfdbplbreak #break the loop if we're out of space (should be done writing msd)
- j sfdbackwardsprintloop #else continue printing backwards.
- sfdbplbreak:
- addi $a1, $a1, 1 #increment the source pointer.
- addi $a0, $a0, 1 #increment the dest pointer.
- j sfloop #return to normal operation.
- sfhex:
- add $t4, $t2, $0 #we're going to be screwing with this one.
- li $t5, 0 #place to count how many digits are needed.
- sfhsizeloop:
- div $t4, $t4, 16 #drop a digit from the number
- addi $t5, $t5, 1 #increment the digit counter
- blt $t4, 1, sfhslbreak #stop the loop if there's no digits left.
- j sfhsizeloop
- sfhslbreak:
- add $t5, $t5, $a0 #convert $t5 to the dest pointer for the backwards print loop
- add $t6, $a0, $0 #save the original dest pointer so we can tell when we've reached it.
- add $a0, $t5, $0 #set the global dest pointer to where the end will be. ($t5==$a0)
- sfhbackwardsprintloop:
- rem $t3, $t2, 16 #grab digit
- addi $t3, $t3, '0' #convert to char (0-9)
- ble $t3, '9', sfhbplnumeral #if the digit <= 9, we don't need to boost it to ascii letter range.
- addi $t3, $t3, 7 #this should change ':' to 'A' (value 10)
- sfhbplnumeral:
- sb $t3, ($t5) #store least digit first
- addi $t5, $t5, -1 #decrement temporary dest pointer
- div $t2, $t2, 16 #actually divide int by 10 now that we've grabbed a digit.
- blt $t5, $t6, sfhbplbreak #break the loop if we're out of space (should be done writing msd)
- j sfhbackwardsprintloop #else continue printing backwards.
- sfhbplbreak:
- addi $a1, $a1, 1 #increment the source pointer.
- addi $a0, $a0, 1 #increment the dest pointer.
- j sfloop #return to normal operation.
- sfstring:
- lbu $t3, ($t2) #load character from string
- beqz $t3, sfstrnullterm #item string has terminated, return to normal operation.
- sb $t3, ($a0) #store character in result string
- addi $a0, $a0, 1 #increment dest pointer
- addi $t2, $t2, 1 #increment item source pointer
- j sfstring
- sfstrnullterm:
- addi $a1, $a1, 1 #increment the source pointer
- j sfloop
- sfchar:
- sb $t2, ($a0) #print char into string
- addi $a0, $a0, 1 #increment dest pointer
- addi $a1, $a1, 1 #increment source pointer
- j sfloop #return to normal operation.
- sfendstring:
- sub $v0, $a0, $t7 #string length = end address - start address
- jr $ra #kthxbye (sorry for trashing your temps. I use them alot)
Add Comment
Please, Sign In to add comment