CS232 MIPS Coding Example 1

Here is a video showing me translate two simple C functions to MIPS, vocalizing my thought process as I write the code.

Go ahead an familiarize yourself with the C code for each function before watching the videos, since they assume familiarity with the code. The first function counts the number of times a character is found in a string; the second counts the number of times one string is found (in its entirety) in another string.

Here are complete (testable) versions of the C code and the MIPS code for both functions.

Example 1: count_letters


Here is the C code I translate:
// This function iterates through the character string "str" (which is of
// length "str_len" and counts how many instances there are of the
// character "c".
int
count_letters(char str[], int str_len, char c) {
  int count = 0;
  for (int i = 0 ; i < str_len ; ++ i) {
	 if (str[i] == c) {
		count ++;
	 }
  }
  return count;
}
Here is the resulting MIPS code:
count_letters:
	li	$v0, 0		# count
	li	$t0, 0		# i
cl_loop:
	bge	$t0, $a1, cl_exit
	add	$t1, $a0, $t0	# &A[i]
	lb	$t2, 0($t1)	# A[i]
	bne	$t2, $a2, cl_skip

	add	$v0, $v0, 1
	
cl_skip: 
	 add	$t0, $t0, 1
	 j	cl_loop

cl_exit:
	jr	$ra

Example 2: count_substring


Here is the C code I translate:
// This function iterates through the character string "str" (which is of
// length "str_len" and counts how many instances there are of the
// string "sub_str" (which is of length "substr_len"). 
int
count_substring(char str[], int str_len, char sub_str[], int substr_len) {
  int count = 0;
  for (int i = 0 ; i < (str_len - substr_len) ; ++ i) {
    int match = TRUE;
    for (int j = 0 ; j < substr_len ; ++ j) {
      if (str[i+j] != sub_str[j]) {
        match = FALSE;
        break;
      }
    }
    if (match) {
      count ++;
    }      
  }
  return count;
}
Note: in my haste, I hadn't test "count_substring" before recording this video. I had a bug in my C code. The outer loop condition i < (str_len - substr_len) should be i <= (str_len - substr_len) (note the less than or equal in the second). I discovered this in the debugging of this MIPS function as I show in the debugging videos. Here is the resulting MIPS code:
count_substring:
	li	$v0, 0		# count
	li	$t0, 0		# i
	sub	$t1, $a1, $a3	# str_len - substr_len
cs_loop:
	bge	$t0, $t1, cs_exit	

	li	$t2, 1	  	# match = TRUE
	li	$t3, 0		# j
	
cs_iloop:
	bge	$t3, $a3, cs_done_inner

	add	$t4, $a0, $t0	# &str[i]
	add	$t4, $t4, $t3	# &str[i+j]
	lb	$t4, 0($t4)	# str[i+j]
	add	$t5, $a2, $t3	# &sub_str[j]
	lb	$t5, 0($t5)	# sub_str[j]
	beq 	$t4, $t5, cs_skip

	li	$t2, 0		# match = FALSE
	j	cs_done_inner	# break

cs_skip:
	add	$t3, $t3, 1	# j ++
	j	cs_iloop

cs_done_inner:
	beq	$t2, $0, cs_skip2

	add	$v0, $v0, 1	# count ++

cs_skip2:
	add	$t0, $t0, 1	# i ++
	j	cs_loop

cs_exit:
	jr	$ra		# return count
In this second example, during the recording, I forgot to write the cs_skip label in front of the add $t3, $t3, 1 # j++ instruction. This bug would be detected when the code is loaded into xspim, because the assembler would fail to compile the branch to cs_skip because it couldn't find a label to which to connect the branch (a syntax error of sorts). I found it when I was typing in the code.


email