How to concatenate string in MIPS? - mips

How do I concatenate a string in MIPS? I think I will somehow have to know the length of the string?

Quick and dirty:
# String concatenate
.text
# Copy first string to result buffer
la $a0, str1
la $a1, result
jal strcopier
nop
# Concatenate second string on result buffer
la $a0, str2
or $a1, $v0, $zero
jal strcopier
nop
j finish
nop
# String copier function
strcopier:
or $t0, $a0, $zero # Source
or $t1, $a1, $zero # Destination
loop:
lb $t2, 0($t0)
beq $t2, $zero, end
addiu $t0, $t0, 1
sb $t2, 0($t1)
addiu $t1, $t1, 1
b loop
nop
end:
or $v0, $t1, $zero # Return last position on result buffer
jr $ra
nop
finish:
j finish
nop
.data
str1:
.asciiz "Hello "
str2:
.asciiz "world"
result:
.space 200
If you don't understand something, don't hesitate to ask.
Have fun :)

Related

My assembler code has this error: "invalid program counter value: 0x00000000 Go: execution terminated with errors"

.data
prompt2: .asciiz "please enter the elements one by one:"
prompt3: .asciiz "the array is ordered as follows: "
prompt4: .asciiz "-- Program is finished running --"
str1: .asciiz ","
newLine: .asciiz "\n"
.text
addi $sp,$sp,-24
sw $ra,0($sp)
sw $s4,4($sp)
sw $a2,8($sp)
sw $s3,12($sp)
sw $s0,16($sp)
sw $s2,20($sp)
main:
# read n from console
li $v0 5
syscall
move $a2 $v0 #tagghiir t0 be a2 (n)
# allocate dynamic memory
sll $a0 $v0 2 # sll performs $a0 = $v0 x 2^2
li $v0 9 #9 is the system code for service(sbrk) whoes work is
syscall #to allocate dynamic memory
move $a1 $v0 #t2 saved address of heap #taghiir t2 to a1
#saved for printing
li $v0, 4 # $system call code for print_str
la $a0, prompt2 # $address of string to print
syscall
move $t1 $zero
move $t4,$a1
inputLoop:
bge $t1 $a2 exit1
# read in and store int
li $v0 5
syscall
sw $v0 0($t4)
addi $t1 $t1 1
addi $t4 $t4 4
li $v0, 4 # $system call code for print_str
la $a0, newLine # $address of string to print
syscall
j inputLoop
exit1:
jal sort
li $v0, 4 # $system call code for print_str
la $a0, prompt3 # $address of string to print
syscall
move $t3,$zero
move $t4 ,$a1
outputLoop:
bge $t3 $a2 exit2
#inaro azoon yki copy krdm
lw $t6, 0($t4)
li $v0, 1
move $a0, $t6
syscall
# read in and store int
addi $t3 $t3 1
addi $t4 $t4 4
blt $t4,$a1 ,comma
# bne $t5,$zero,comma
comma:
li $v0, 4 # $system call code for print_str
la $a0, str1 # $address of string to print
syscall
j outputLoop
exit2:
li $v0, 10
syscall #for finishing the program
swap:
move $a3,$a3
move $a1,$s4
# move $t5,$zero # its for our temp variable in c code
move $t4 ,$a1 #t4 is now the base address of heap
sll $t6 , $a3,2 # s1 is the given k
add $t6,$t4,$t6 # heap address + k*4
lw $t3,0($t6) #khoone k e heap
lw $t5,4($t6) #khoone k+1 heap
sw $t5,0($t6)
sw $t3,4($t6)
jr $ra
sort:
# move $s0,$zero #i=t0
move $s4,$a1 #base address of heap
addi $t5,$a2,-1 # meghdare i
move $s2,$zero #its the flag
while:
addi $s2,$s2,1
move $a3,$zero #j #taghiir s1 be a3 (haman j va k
forLoop:
bge $a3,$t5,outOfLoop
sll $t6,$a3,2 #j
add $t1,$t6,$a1 #v+j
lw $t7,0($t1) #t7=heap[j]
lw $t8,4($t1) #t8=heap[j+1]
blt $t7,$t8,outOfIf
move $s4,$a1
move $s3,$a3
jal swap
addi $s2,$s2,-1
outOfIf:
addi $a3,$a3,1 #j++
outOfLoop:
addi $t5,$t5-1 #i--
bgt $s2,$zero,exit_outter #if a>=b break
ble $t5,$zero,exit_outter #if b=< c break
j while
exit_outter:
lw $ra,0($sp)
lw $s4,4($sp)
lw $a2,8($sp)
lw $s3,12($sp)
lw $s0,16($sp)
lw $s2,20($sp)
addi $sp,$sp,24
jr $ra
Where am I going wrong?

How to store 2 chars in one byte in MIPS?

My question is, it is possible to store 2 chars in one byte in mips?
If yes, how can i do that? I've already searched alot in the internet and i cannot find how to do that, i also tryied to copy to an empty array of strings, but it doesnt work.
.data
string: .asciiz "ola"
string2: .asciiz ""
a: .ascii "a"
a1: .ascii "b"
e: .ascii "e"
e1: .ascii "f"
i: .ascii "i"
i1: .ascii "j"
o: .ascii "o"
o1: .ascii "p"
u: .ascii "u"
u1: .ascii "v"
tam: .word 3
.text
main:
lw $t6, tam #string length
lb $t1, string($t0) #read bit by bit
la $a0, string
la $a1, string2
lb $s0, a #save in register the char that we want to search
lb $s1, a1 #save in register the char that we want to replace
beq $t0, $t6, done
beq $t1, $s0, continua #if the char of (bit by bit) its like the char of chars, swap it
bne $t1, $s0, else #if not, saves
else:
lb $s0, e
lbu $s1, e1
beq $t1, $s0, continua
bne $t1, $s0, else2
else2:
lb $s0, i
lb $s1, i1
beq $t1, $s0, continua
bne $t1, $s0, else3
else3:
lb $s0, o
lb $s1, o1
beq $t1, $s0, continua
bne $t1, $s0, else4
else4:
lb $s0, u
lb $s1, u1
beq $t1, $s0, continua
bne $t1, $s0, store
continua:
move $v0, $a0
sb $s1, string($t0) #do the swap
addi $t0, $t0, 1 #+1 in the index
j main
store:
move $v0, $a0
sb $t1, string($t0) #saves
addi $t0, $t0, 1 #+1 in the index
j main
done:
move $a1, $v0
la $a0, string
li $v0, 4
syscall
li $v0, 10
syscall
Kind regards.

A MIPS palindrome

The current code that I have looks as such. It can successfully read if a string is a palindrome when punctuation is not entered.
.data
buffer: .space 80
input: .asciiz "Enter a string: "
output: .asciiz "Your string: "
paly: .asciiz "This is a palindrome "
notp: .asciiz "This is not a palindrome"
.text
main:
li $v0, 4 # system call code for print_str
la $a0, input # address of string to print
syscall # print the input
li $v0, 8 # code for syscall read_string
la $a0, buffer # tell syscall where the buffer is
li $a1, 80 # tell syscall how big the buffer is
syscall
la $a0, buffer # move buffer into a0
li $v0, 4 # print buffer
syscall
la $t1, buffer # begining of the string
la $t2, buffer # end of the string
li $t0, 0
loop:
lb $t3,($t2) # load the byte of the end of the string
beqz $t3,endl # if its equal to 0 then branch out of the loop
addu $t2, $t2,1 # if in loop the increment to next character
jal loop # repeat the loop
upper:
addi $t4,$t4,32
j lowered
lowered:
addi $t0,$t0,1
sb $t4, 0($a0)
addi $a0,$a0,1
j loop
endl:
subu $t2, $t2, 2 # subtracting 2 to move back from \0 and \n
check:
#lb $t4, 0($a0)
#beqz $t4, after
#beq $t4, 10, after
#slti $t2, $t4, 91
#li $t3, 1
#beq $t2, $t3, upper
bge $t1, $t2, palindrome # if both sides are equal then its a palindrome
# call palindrome
lb $t3, ($t1) # load the byte into register t3
lb $t4, ($t2) # load the end byte into register t4
bne $t3, $t4, notpaly # if the two register bytes are not equal its it not a palindrome
addu $t1, $t1, 1 # increment the beginning of the string to next char
subu $t2, $t2, 1 # decrement end of string to next char to compare
jal check # repeat the loop
palindrome:
la $a0, paly # calling paly from data
li $v0, 4 # call for reading string
syscall
jal exit # jump to end
notpaly:
la $a0,notp # calling notp from data
li $v0, 4 # call for reading string
syscall
jal exit # jump to end
after:
li $v0, 4
la $a0, output
syscall
la $a0, buffer
li $v0, 4
syscall
exit:
li $v0 ,10 # call to end program
syscall # call os
Now I know I need to implement code such as to make uppercase lowercase, and to remove punctuation.
With my already stored bits in check: I have some commented code, and this would be to to test if a character is uppercase, then jump to the function and lower it by adding 32. But it does not compile correctly and i am assuming this is because I am not storing the bits correctly.
#lb $t4, 0($a0)
#beqz $t4, after
#beq $t4, 10, after
#slti $t2, $t4, 91
#li $t3, 1
#beq $t2, $t3, upper

Count number of lowercase letters

So I have created this program to count the number of lowercase letters in a string. The problem I am having is that when I reach the end of the string and the nl character is reached, the line beq $t0, $t1, end is not being executed; it just continues indefinitely. I'm not sure what I'm doing incorrectly.
.data
msg1: .word 0:24
.text
.globl main
main:
addu $s0, $0, $ra
li $v0, 8
la $a0, msg1
la $a1, 100
syscall
loop:
lb $t0, 4($a0)
li $t1, 0x0a
beq $t0, $t1, end
continue:
li $t1, 'a'
blt $t0, $t1, count
li $t1, 'z'
bgt $t0, $t1, count
count:
addi $t4, $t4, 1
j loop
end:
li $v0, 1
addu $a0, $t2, $0
syscall
jr $ra
You compare 4($a0) with 0x0a on each iteration of the loop, but you never change $a0 in the loop, so you are not advancing through your string and never look at the \n at the end of the string.
There also are a few other bugs in your code.
Use this at the start of your loop:
loop:
lb $t0, 0($a0)
addiu $a0, $a0, 1
...

MIPS prompt for a string and exchange the case of each character

I am writing a MIPS program that prompts the user for a string and then parse the string exchanging the case of each character.
for example ->
Hey You becomes hEY yOU.
My question is, how do i make it do nothing if it encounters a space ? Any help would be great!
.data
string4:.space 82 # space for input string
strPrompt:.asciiz "Please enter a string: "
.text
.globl main
main:
la $a0, strPrompt # print prompt
li $v0, 4
syscall
la $a0, string4 # read string
li $a1, 80
li $v0, 8
syscall
la $a0, string4 # print string
li $v0, 4
syscall
la $t0, string4 # $t0 = &string4[0]
li $t1, 0
loop4:
lb $t1, 0($t0)
nop
nop
beqz $t1, done4 # if $t1 == NUL, we are done
bgt $t1, 90, else # if char > 90 its a lower case
nop
addi $t1, $t1, 0x20 # if < 90 its upper case add 32
sb $t1, 0($t0)
addi $t0, $t0, 1 # add 1 to pointer
j loop4 # jump back to loop
nop
else:
addi $t1, $t1, -0x20
sb $t1, 0($t0)
addi $t0, $t0, 1
j loop4
nop
done4:
Here's a branchless way of changing the case of a character in $t1 if it's in the range A..Z or a..z, and do nothing if it's outside that range:
# if (upper($t1) >= 'A' && upper($t1) <= 'Z') $t2 = 1; else $t2 = 0;
andi $t3,$t1,0xDF # clear bit 5, if $t1 was an alphabetic character $t3 will now be uppercase
li $t2,'A'-1
sltu $t2,$t2,$t3
sltiu $t3,$t3,'Z'+1
and $t2,$t2,$t3
sll $t2,$t2,5 # $t2 = 0x20, or 0
xor $t1,$t1,$t2 # either swap case or do nothing