PDA

View Full Version : mips assembly comparing strings


SpiffyEh
Apr19-10, 12:14 PM
1. The problem statement, all variables and given/known data
I need to compare a user input with a string thats already in the program.

If the operation entered is ‘*’, you should print out the product of the 2 numbers; if the
operation entered is ‘/’, you should print out the quotient and the remainder.

the multiplication and division is implemented using the algorithms

3. The attempt at a solution

The instructor provided code for the comparison of the user entered operation with a string in the code. I'm having issues with this code, maybe I'm just using it wrong. This is the provided code:
la $a0, operator # puts entered stuff into "operator" string
li, $a1, 3 # reads 3 things: a character, an enter, and a null
li $v0, 8 # load the "read string" syscall number
syscall
la $s2, operator # operator = s2 = value returned
lbu $t4, 0($s2) # loads the character entered by the user
la $t0, addSign # loads the address of the add symbol
lbu $t5, 0($t0) # loads the add symbol
bne $t4, $t5, notAdd #if the charater entered isn't a +, move on

I have the program printing a few lines for input of numbers and such and then I have this:
la $a0, operation # prints the operation string
li $v0, 4
syscall

la $a0, operator # puts entered data into the operator string
li $a1, 3 # reads 3 things: a character, an enter, and a null
li $v0, 8 # loads the read string syscall number
syscall
la $s2, operator # operator = s2 = value returned
lbu $t4, 0($s2) # loads the character entered bu the user
la $t0, multSign # loads the address of the add symbol
lbu $t5, 0($t0) # loads the add symbol
bne $t4, $t5, notMult # if the character entered isn't a * move on
add $a0, $s0, $0
add $a1, $s1, $0
jal multiplyFunc
add $s3, $v0, $0

add $a0, $s0, $0
li $v0, 1
syscall

la $a0, multSign
li $v0, 4
syscall

add $a0, $s1, $0
li $v0, 1
syscall

la $a0, product
li $v0, 4
syscall

add $a0, $s3, $0
li $v0, 1
syscall
j Exit


no matter what I input it always multiplies and the weird thing is that if i put in the numbers 3 and 2 for examle with the operation / it goes to multiply and it prints "3/2; product = 6" when I'm not printing the user entered operation between the operands, I'm printing the string in the program. I have the strings declared like this:
product: .asciiz ": product="
operator: .ascii ""
multSign: .asciiz "*"
divSign: .asciiz "/"

I have no idea what i'm doing wrong here, everything besides this works.

Mark44
Apr19-10, 02:09 PM
1. The problem statement, all variables and given/known data
I need to compare a user input with a string thats already in the program.

If the operation entered is ‘*’, you should print out the product of the 2 numbers; if the
operation entered is ‘/’, you should print out the quotient and the remainder.

the multiplication and division is implemented using the algorithms

3. The attempt at a solution

The instructor provided code for the comparison of the user entered operation with a string in the code. I'm having issues with this code, maybe I'm just using it wrong. This is the provided code:
la $a0, operator # puts entered stuff into "operator" string
li, $a1, 3 # reads 3 things: a character, an enter, and a null
li $v0, 8 # load the "read string" syscall number
syscall
la $s2, operator # operator = s2 = value returned
lbu $t4, 0($s2) # loads the character entered by the user
la $t0, addSign # loads the address of the add symbol
lbu $t5, 0($t0) # loads the add symbol
bne $t4, $t5, notAdd #if the charater entered isn't a +, move on

I have the program printing a few lines for input of numbers and such and then I have this:
la $a0, operation # prints the operation string
li $v0, 4
syscall

la $a0, operator # puts entered data into the operator string
li $a1, 3 # reads 3 things: a character, an enter, and a null
li $v0, 8 # loads the read string syscall number
syscall
la $s2, operator # operator = s2 = value returned
lbu $t4, 0($s2) # loads the character entered bu the user
la $t0, multSign # loads the address of the add symbol
lbu $t5, 0($t0) # loads the add symbol
bne $t4, $t5, notMult # if the character entered isn't a * move on
add $a0, $s0, $0
add $a1, $s1, $0
jal multiplyFunc
add $s3, $v0, $0

add $a0, $s0, $0
li $v0, 1
syscall

la $a0, multSign
li $v0, 4
syscall

add $a0, $s1, $0
li $v0, 1
syscall

la $a0, product
li $v0, 4
syscall

add $a0, $s3, $0
li $v0, 1
syscall
j Exit


no matter what I input it always multiplies and the weird thing is that if i put in the numbers 3 and 2 for examle with the operation / it goes to multiply and it prints "3/2; product = 6" when I'm not printing the user entered operation between the operands, I'm printing the string in the program. I have the strings declared like this:
product: .asciiz ": product="
operator: .ascii ""
multSign: .asciiz "*"
divSign: .asciiz "/"

I have no idea what i'm doing wrong here, everything besides this works.

I think your problem might be in this code.

la $s2, operator # operator = s2 = value returned
lbu $t4, 0($s2) # loads the character entered bu the user
la $t0, multSign # loads the address of the add symbol
lbu $t5, 0($t0) # loads the add symbol
bne $t4, $t5, notMult # if the character entered isn't a * move on


You're comparing the wrong things, plus you're storing only two of the three things you need. For example, if the user enters 8/4<CR>, the code above picks out the first operand and the operator, but not the second operand. In this example, 8 gets stored in t4, and '*' gets stored in t5. The branch instruction transfers control to the notMult label if the bytes in t4 and t5 aren't equal, which they clearly are not.

What you want to do is to store the byte at 1(%s2) in t4, and compare that with what's in t5. That way you'll be comparing / with *.

Other comments:
Your operator string is an empty string. It doesn't look to me like you are allocating any space for it. I might be missing something, but if it's the case that you don't have any memory for operator, when the read string syscall returns, the characters stored in operator could overwrite some other variables. Whenever you're working with pointers and write to the address referenced by the pointer, make sure the pointer points to a block of memory that can be written to without clobbering anything else.

Also, I think operator is a misleading name for this variable. If I understand your code, after the read_string system call, operator will be a string such as "3*4<return><null>". A better name for this string might be expression or operation or the like. The operator in this string is '*'.

Minor point: this code
la $t0, multSign # loads the address of the add symbol
has a misleading comment. You're loading the address of the mult. symbol.

SpiffyEh
Apr20-10, 09:57 AM
Thank you for the help, i'm working on trying it now. How would i allocate memory for the string? Before I posted I spent a bunch of time messing with that because I thought it was my problem. I was never taught how to do that

SpiffyEh
Apr20-10, 10:28 AM
I looked it up online, it's hard to find mips assembly syntax online. The issue was the allocation of space for the string. I fixed that and everything works. Thank you so much

Mark44
Apr20-10, 01:00 PM
Cool! Glad that I could point you in the right direction, even though I don't "speak MIPS." Still, assembly is assembly, and if you understand on (x86 for me) you can more or less get the drift in some other kind.