bieaisar
bieaisar

Reputation: 29

Comparing Two Strings in MIPS

I was trying to compare two strings because of my adding integers code which i posted here before. I could take string from user, also convert that to integer, but i have faced a problem during comparison of string (max size is 20 and if string is less than 20, there will be spaces) read from user and my character " * ". I thought that if i can compare them and they are not equal, i convert to integer and continue to adding, if they are equal it will exit from loop.

I wrote a simple code for comparing two strings, however that didn't give the result. Here is my code;

.data
  str1:  .asciiz "Comp"
  str2:  .asciiz "Comp"
.text

main:
  la   $s2, str1
  la   $s3, str2
  move $s6, $s2
  move $s7, $s3
  li   $s1, 5


  beq  $s6, $s7, exit

  move $a0, $s1   
  li   $v0, 1
  syscall


exit:  

  li   $v0, 10      
  syscall

After i have checked QtSpim's registers $s6 and $s7, i observed that there are different values. How can i compare two strings? Thank you.

Upvotes: 1

Views: 27225

Answers (3)

pewdie2pie
pewdie2pie

Reputation: 16

A simple String Compare compiled using MIPS, prints ASCII difference of first unmatched character it encounters

.text
.globl main

main:
    li $v0, 4
    la $a0, msg1
    syscall

    li $v0, 8
    la $a0, string1
    li $a1, 99
    syscall

    li $v0, 4
    la $a0, msg2
    syscall

    li $v0, 8
    la $a0, string2
    li $a1, 99
    syscall

    lb $t5, endline

    # compare each bit
    la $t1, string1
    la $t2, string2

    loop:
    # load the characters 
        lb $t3, 0($t1)
        lb $t4, 0($t2)
    # check if equal, if not stop loop, if equal, then continue 
        sub $t6, $t3, $t4

        beq $t6, $zero, continueEqual
        j end_loop

    continueEqual:
    # if t3 or t4 == '\n' stop loop
        beq $t3, $t5, end_loop
    # continue again, by incrementing both address by one
        addi $t1, $t1, 1
        addi $t2, $t2, 1
        j loop

    end_loop:

        beq $t6, $zero, same

        notSame:
        li $v0, 4
        la $a0, msg4
        syscall

        j printRes
        
        same:
            li $v0, 4
            la $a0, msg3
            syscall

    printRes:
        li $v0, 1
        move $a0, $t6
        syscall
        li $v0, 4
        la $a0, endline
        syscall

exit:
    li $v0, 10
    syscall


.data

msg1: .asciiz "Enter string-1: "
msg2: .asciiz "Enter string-2: "
msg3: .asciiz "Same\n"
msg4: .asciiz "Not Same\n"
endline: .asciiz "\n"
string1: .space 100
string2: .space 100

Upvotes: 0

Craig Estey
Craig Estey

Reputation: 33601

I've adapted your program to prompt the user for strings, so you can try many values quickly. The cmploop is the "meat" of the string compare, so you can just use that if you wish.

Here's it is [please pardon the gratuitous style cleanup]:

    .data
prompt:     .asciiz     "Enter string ('.' to end) > "
dot:        .asciiz     "."
eqmsg:      .asciiz     "strings are equal\n"
nemsg:      .asciiz     "strings are not equal\n"

str1:       .space      80
str2:       .space      80

    .text

    .globl  main
main:
    # get first string
    la      $s2,str1
    move    $t2,$s2
    jal     getstr

    # get second string
    la      $s3,str2
    move    $t2,$s3
    jal     getstr

# string compare loop (just like strcmp)
cmploop:
    lb      $t2,($s2)                   # get next char from str1
    lb      $t3,($s3)                   # get next char from str2
    bne     $t2,$t3,cmpne               # are they different? if yes, fly

    beq     $t2,$zero,cmpeq             # at EOS? yes, fly (strings equal)

    addi    $s2,$s2,1                   # point to next char
    addi    $s3,$s3,1                   # point to next char
    j       cmploop

# strings are _not_ equal -- send message
cmpne:
    la      $a0,nemsg
    li      $v0,4
    syscall
    j       main

# strings _are_ equal -- send message
cmpeq:
    la      $a0,eqmsg
    li      $v0,4
    syscall
    j       main

# getstr -- prompt and read string from user
#
# arguments:
#   t2 -- address of string buffer
getstr:
    # prompt the user
    la      $a0,prompt
    li      $v0,4
    syscall

    # read in the string
    move    $a0,$t2
    li      $a1,79
    li      $v0,8
    syscall

    # should we stop?
    la      $a0,dot                     # get address of dot string
    lb      $a0,($a0)                   # get the dot value
    lb      $t2,($t2)                   # get first char of user string
    beq     $t2,$a0,exit                # equal? yes, exit program

    jr      $ra                         # return

# exit program
exit:
    li      $v0,10
    syscall

Upvotes: 3

wallyk
wallyk

Reputation: 57774

The comparison relates the pointers. There needs to be a dereferencing in there.

lb  $s6, ($s2)
lb  $s7, ($s3)

Also, there needs to be checks for end of string.

lb  $s6, ($s2)
bz  eos
lb  $s7, ($s3)
bz  eos

Upvotes: 0

Related Questions