# InvertText.s # # Author: Andrea Micheloni (http://www.tankmiche.com) # License: Creative Commons Attribute-NonCommercial-ShareAlike 3.0 # Tested on: xspim (spim v7.3) # Description: Waits for an input text (32 chars max), then outputs the same text reversed # Comments are in pseudo-code # .globl main .data fub: .space 32 fin: .space 4 buf: .space 32 intro: .asciiz "\nWelcome! Type something (max 32 chars), and I will output it in reverse: \n\n" out: .asciiz "\nAnd the reversed string is: \n" .text main: li $v0, 4 # mode = print_string la $a0, intro # str = intro syscall # >> output li $v0, 8 # mode = read_string la $a0, buf # buffer = buf li $a1, 33 # length = 32 syscall # input >> buf lui $s0, 0x1001 # s0 = 0x10010000 lui $s1, 0x1001 # s1 = 0x10010000 addi $s1, $s1, 0x0020 # s1 += 0x0020 li $t0, 32 # t0 = 32 loop: incr: add $s3, $s1, $t0 # s3 = s1+t0 addi $t0, -4 # t0-- lw $t1, 0($s3) # t1 = mem[ s1 + 0 ] beq $t1, $0, incr # if ( t1 == 0 ) -> incr # The following instructions reverse the loaded word # stored in $t1, it changes from 0xABCDEFGH to 0xGHEFCDAB andi $t2, $t1, 0x00ff # t2 = 0x000000yy sll $t2, $t2, 24 # t2 = 0xyy000000 andi $t3, $t1, 0xff00 # t3 = 0x0000yy00 sll $t3, $t3, 8 # t3 = 0x00yy0000 srl $t1, $t1, 16 # t1 = 0x0000yyyy andi $t4, $t1, 0x00ff # t4 = 0x000000yy sll $t4, $t4, 8 # t4 = 0x0000yy00 andi $t5, $t1, 0xff00 # t5 = 0x0000yy00 srl $t5, $t5, 8 # t5 = 0x000000yy or $t5, $t5, $t4 # t5 = t5 OR t4 or $t3, $t3, $t2 # t3 = t3 OR t2 or $t1, $t3, $t5 # t1 = t5 OR t3 sw $t1, 0($s0) # mem[ s0 + 0 ] = t1 addi $s0, $s0, 4 # s0 += 4 bgtz $t0, loop # if( t0 > 0 ) -> loop li $v0, 4 # mode = print_string la $a0, out # str = out syscall # >> output # # Ok, we have the text in memory (buf). But what if it starts with the null char? # it would print nothing at all, thinking the string is finished! # so we have to find where the first NULL is, and print from that location on. # lui $t2, 0x00FF # t2 = 0x00FF0000 li $t0, 3 # t0 = 3 lui $s0, 0x1001 # s0 = 0x10010000 lw $t1, 0($s0) # t1 = mem[ s0 + 0 ] and $t3, $t2, $t1 # t3 = t2 AND t1 beq $t3, $0, end # if( t3 == 0 ) -> end addi $t0, $t0, -1 # t0-- srl $t2, $t2, 8 # t2 = 0x0000FF00 and $t3, $t2, $t1 # t3 = t2 AND t1 beq $t3, $0, end # if( t3 == 0 ) -> end addi $t0, $t0, -1 # t0-- srl $t2, $t2, 8 # t2 = 0x000000FF and $t3, $t2, $t1 # t3 = t2 AND t1 beq $t3, $0, end # if( t3 == 0 ) -> end addi $t0, $t0, -1 end: add $a0, $s0, $t0 # str = mem[ s0 + t0 ] syscall # >> output li $v0, 10 # mode = exit syscall # >> quit