# This program manages an array of string pointers. # First, it printes all the non-empty strings. # Second, it prints a row of hyphens for each string, with # one hyphen per character in the original string. .data # The following entries go in the data segment strName: .asciiz "Author: Doug Johnson\n" strTaskA: .asciiz "\nAll non-empty strings.\n\n" strTaskB: .asciiz "\nString bars.\n\n" strEmpty: .asciiz "" strA: .asciiz "This is a string." strB: .asciiz "This is another string." strNewline: .asciiz "\n" strColon: .asciiz ":" strHyphen: .asciiz "-" strings: # This array holds a list of string addresses, # terminated by a 0 address .word strA,strB,strEmpty,strB,strA,0 # stack frame layout # 28($sp) reserved # 24($sp) $ra # 20($sp) unused # 16($sp) $s0 # 12($sp) reserved for callee: $a3 save space # 8($sp) reserved for callee: $a2 save space # 4($sp) reserved for callee: $a1 save space # 0($sp) reserved for callee: $a0 save space .text # The following entries go in the text (program code) segment main: subu $sp,$sp,32 # create stack frame sw $ra,24($sp) # save return address sw $s0,16($sp) # save $s0 # print the name of the program's author la $a0,strName # load name string address li $v0,4 # load print_string code syscall # print # print the task label la $a0,strTaskA # string address li $v0,4 # print_string code syscall # print # look at each string address in the array # print the strings that are not zero length la $s0,strings # $s0 = next address = address(strings) lw $a0,0($s0) # $a0 = strings[0] = address of first string beqz $a0,mainExit # if first address is 0, then quit mainLoopA: lbu $t0,0($a0) # load first byte of the current string beqz $t0,mainIfSkip # if first byte is 0, then empty li $v0,4 # print_string code syscall # print la $a0,strNewline # newline address li $v0,4 # print_string code syscall # print mainIfSkip: addi $s0,4 # point to next string address in array lw $a0,0($s0) # get address of next string bnez $a0,mainLoopA # loop if more strings in array # print the task label la $a0,strTaskB # string address li $v0,4 # print_string code syscall # print # print out bars instead of strings la $a0,strings jal printStringBars mainExit: lw $ra,24($sp) # restore return address lw $s0,16($sp) # restore $s0 addu $sp,$sp,32 # release stack frame jr $ra # return #-------------------------------------------------------------------- # printStringBars(char **strings) # Print one line of hyphens for each string whose address # appears in the strings array. Each line is preceded by # a colon ":". # Only the colon is printed for empty (ie, zero-length) # strings. # $a0 - strings - address of an array of string addresses. The # last entry in the array MUST be 0 because this procedure will keep # looping until it encounters a 0 string address. # This is a non-leaf procedure because it calls procedure printBar. # stack frame layout # 28($sp) reserved # 24($sp) $ra # 20($sp) unused # 16($sp) $s0 # 12($sp) reserved for callee: $a3 save space # 8($sp) reserved for callee: $a2 save space # 4($sp) reserved for callee: $a1 save space # 0($sp) reserved for callee: $a0 save space printStringBars: subu $sp,$sp,32 # create stack frame sw $ra,24($sp) # save return address sw $s0,16($sp) # save $s0 move $s0,$a0 # remember the array address lw $a0,0($s0) # $a0 = strings[0] = address of first string beqz $a0,psbExit # if first address is 0, then quit psbLoop: jal printBar # print hyphen bar addi $s0,4 # point to next string address in array lw $a0,0($s0) # get address of next string bnez $a0,psbLoop # loop if more strings in array psbExit: lw $ra,24($sp) # restore return address lw $s0,16($sp) # restore $s0 addu $sp,$sp,32 # release stack frame jr $ra #-------------------------------------------------------------------- # printBar(char *s) # Print a row of hyphens representing the string s. # The row is preceded by a colon ":". # This is a leaf procedure and no stack frame is needed. # $t0 - address of current byte # $t1 - the byte at 0($t0) printBar: move $t0,$a0 # remember the string to print la $a0,strColon # colon address li $v0,4 # print_string code syscall # print la $a0,strHyphen # hyphen address li $v0,4 # print_string code lbu $t1,0($t0) # load the current byte beqz $t1,pbExit # exit if all done. pbLoop: syscall # print a hyphen addi $t0,1 # point to next byte lbu $t1,0($t0) # load the current byte bnez $t1,pbLoop # loop if not zero pbExit: la $a0,strNewline # newline address li $v0,4 # print_string code syscall # print jr $ra