Search code examples
ccpu-registersmips32

Character Comparison from C to MIPS32


I have been given two functions in C that I need to convert to MIPS32 instructions.

I am new to programming. So far I have tried to understand what is actually happening in the C and then used MIPS instructions to translate the C code to assembly language. I mostly used jump instruction to hop around different parts of the code. I am sure there are probably better ways to use the registers to make the code concise but at this point, I am just trying to get my concepts right and understand string manipulation. After that I will work on optimizing the code.

C Code:

char firstmatch(char *s1, char *s2) {
    char *temp;
    temp = s1;
    do {
        if (strchr(s2, *temp) != 0)
            return temp;
        temp++;
        } while (*temp != 0);
    return 0;
    }

char *strchr(register const char *s, int c) {
    do {
        if (*s == c) {
            return (char*)s;
       }
    } while (*s++);
    return (0);
   }

MIPS Code:

.data

str1: .asciiz "hello \n"    #String 1
str2: .asciiz "meh \n"      #String 2

char_found: .asciiz " is the first character in string s1 that is also in s2 \n"     
char_not_found: .asciiz "No character match between the two strings \n" 


.text

main:

    la $a0, str1    #Loading address of string 1 into register $a0
    la $a1, str2    #Loading address of string 2 into register $a1  


firstmatch:

    move $t0, $a0   #Passing address of str1 from $a0 to $t0        
    move $t1, $a1   #Passing address of str1 from $a1 to $t1
    addi $t2,$t0,0  #Using $t2 register for the temp variable


Load_Bytes:

    lb $t4, 0($t1)  #Loading the first character of str2 
    lb $t3, 0($t2)  #Loading the first character of str1 


strchr:         
    beq   $t4,$t3,Label_1   #Checking for character match. 
    j Label_2       #No match, go to Label_2


Label_1:    #Label to Print character as well as char_found string 
    li $v0, 4           
    la $s0, ($t4)
    syscall
    la $t5, char_found
    syscall 


Label_2:

    addi $t2, $t2, 1    #Incrementing temp by 1
    lb $t6, 0($t2)      #Using t6 to check for NULL character
    beqz $t6, Label_4   #Checking if value at $t2 is 0.
    j Load_Bytes

Label_3:            #Label to print when no character match

    li $v0, 4           
    la $t5, char_not_found
    syscall 


Label_4:

    addi $t1, $t1, 1    #Increment str2 byte by 1 after string 1 iteration reaches the NULLL character
    lb $t7, 0($t1)      #Using t7 to check for NULL character
    beqz $t7, Label_3   #Checking if value at str 2($t1) is 0
    addi $t2, $t0, 0    #Re-initialize string 1
    j Load_Bytes

Currently, my code keeps running endlessly and printing string 1. I suspect that either I am not comprehending the concept of loading addresses and bytes correctly or there is a jump condition that keeps repeating the program. Any help would be appreciated.


Solution

  • .data
    
    str1: .asciiz "HeLlo"           #String 1
    str2: .asciiz "mEadow"          #String 2
    
        char_found: .asciiz " is the first character in string s1 that is also in s2 \n"     #To be printed when character is found
        char_not_found: .asciiz "No character match between the two strings \n"          #To be printed if there is no match        
    
    .text
    
        main:
    
            la $a1,str1             #Loading address of string 1 into register $a1
            la $a2,str2             #Loading address of string 2 into register $a2
    
            move $t0,$a1            #Passing address of str1 from $a1 to temp register $t0      
            move $t1,$a2            #Passing address of str1 from $a2 to temp register $t1
            addi $t2,$t0,0          #Using $t2 register for the temp variable in the code
    
    
        Load_Bytes:
    
            lb $t4, 0($t1)          #Loading the first character of str2 from memory address $t1 to $t4
            lb $t3, 0($t2)          #Loading the first character of str1 from memory address $t2 to $t3
    
    
        strchr:         
            beq $t3,$t4,Label_1     #Checking for character match. If yes, going to Label_1. If not, continue
            jal firstmatch
    
            addi $t1, $t1, 1        #Increment str2 byte by 1 after string 1 iteration reaches the NULLL character
            lb $t7, 0($t1)          #Using t7 as temporary register to check for NULL character in the next step
            beqz $t7, Label_2       #Checking if value at string 2($t1) is 0. If yes, go to Label_5
            addi $t2, $t0, 0        #Re-initialize string 1 to start the compare loop again
            j Load_Bytes            
    
    
        firstmatch:
    
            addi $t2, $t2, 1        #Incrementing temp by 1
            lb $t6, 0($t2)          #Using t6 as temporary register to check for NULL character in the next step
            bnez $t6, Load_Bytes        #Checking if value at $t2 is 0. If yes, going to Label_2. If not, continue and iterate the loop 
            jr $ra  
    
    
        Label_1:                #Label to Print character as well as char_found string above simultaneously
    
            la $a0,($t4)
            li $v0, 11          
            syscall 
    
            la $a0, char_found
            li $v0, 4
            syscall
    
            li $v0,10
            syscall     
    
        Label_2:                #Label to print when no character match is found
    
            la $a0, char_not_found
            li $v0, 4           
            syscall 
    
            li $v0, 10
            syscall