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
...
Related
Here is my code that calculates the sum of two arrays and then prints them in a message to the the console. I would now like to compare my two array sums and return the correct message prompt depending on which array is larger. I feel like I'm very close because I tried to follow the logic from the first printed statements but how can I compare register $s7 & $s8 and then declare one the larger array through my message prompt I have set up? I'm using this emulator: https://cpulator.01xz.net/?sys=mipsr5-spim
.data
x: .word 1,2,3,4,5,6,7,8,9,10
iterator: .word 0
size: .word 9
prompt: .asciiz "The total sum of the array is equal to: "
.text
main:
la $s0, prompt
la $t0, x
lw $t1, iterator
lw $t2, size
begin_loop:
bgt $t1, $t2, exit_loop
sll $t3, $t1, 2
addu $t3, $t3, $t0
lw $t6, 0($t3)
addu $s7, $s7, $t6
addi $t1, $t1, 1
j begin_loop
exit_loop:
li $v0, 4
la $a0, prompt
syscall
li $v0, 1
la $a0, ($s7)
syscall
.data
x2: .word 5,6,7,8,9,10,11,12,13,14
iterator2: .word 0
size2: .word 9
prompt2: .asciiz "The total sum of array 2 is equal to: "
prompt3: .asciiz "The larger array is array 1"
prompt4: .asciiz "The larger array is array 2"
.text
main2:
la $s0, prompt2
la $t0, x2
lw $t1, iterator2
lw $t2, size2
begin_loop2:
bgt $t1, $t2, exit_loop2
sll $t3, $t1, 2
addu $t3, $t3, $t0
lw $t6, 0($t3)
addu $s8, $s8, $t6
addi $t1, $t1, 1
j begin_loop2
exit_loop2:
li $v0, 4
la $a0, prompt2
syscall
li $v0, 1
la $a0, ($s8)
syscall
slt $t1,$s7,$s8 # checks if $s0 > $s1
beq $t1,1,prompt3 # if $s7 > $s8, goes to prompt3
beq $t1,$zero,prompt4 # if $s8 < $s7, goes to prompt4
li $v0, 4
la $a0, prompt3
syscall
li $v0, 4
la $a0, prompt4
syscall
The basic flow of the program is as follows:
1. Print the original content of array.
2. Ask the user for two indices X and Y.
3. Swap the two elements if Array[X] > Array[Y].
4. Print the modified array only if swapping occurs.
.data
array: .word 8, 2, 1, 6, 9, 7, 3, 5, 0, 4
newl: .asciiz "\n"
.text
la $a0, array
li $a1, 10
jal printArray
#Ask the user for two indices
li $v0, 5 #System call code for read_int
syscall
addi $t0, $v0, 0 # first user input in $t0
li $v0, 5 #System call code for read_int
syscall
addi $t1, $v0, 0 # second user input in $t1
swap : li $a1, 0 #inx1
li $a2, 0 #inx2
sll $t0, $a1, 2 # $t0 = inx1* 4
add $t0, $t0, $a0 # $t0 is the address of A[$a1]
sll $t3, $a2, 2 # $t3 = inx2* 4
add $t3, $t3, $a0 # $t3 is the address of A[$a2]
lw $t1, 0($t0) # $t1 = A[$a1]
lw $t2, 0($t3) # $t2 = A[$a2]
ble $t1, $t2, noPrint# if A[$a1] <=A[$a2] goto noPrint
sw $t1, 0($t3) # do the swap
sw $t2, 0($t0) # do the swap
syscall
jal printArray
printArray:
addi $t1, $a0, 0 #$t1 is the pointer to the item
sll $t2, $a1, 2 #$t2 is the offset beyond the last item
add $t2, $a0, $t2 #$t2 is pointing beyond the last item
loop: beq $t1, $t2, end
lw $t3, 0($t1) #$t3 is the current item
li $v0, 1 # system call code for print_int
addi $a0, $t3, 0 # integer to print
syscall # print it
addi $t1, $t1, 4
j loop # Another iteration
end:
li $v0, 4 # system call code for print_string
la $a0, newl #
syscall # print newline
jr $ra # return from this function
noPrint:
li $v0, 10 # system call code for exit
syscall # terminate program
I'm having problems with swap function. It doesn't print anything on console window(using QtSpim). Can you please recommend any suggestion?
I am currently beginning to study the MIPS language and I am trying to write a bubble sort code in MIPS, but I guess I have made a mistake somewhere and i can't seem to find it. I believe I am storing elements properly but I don't know why it is not working. Here is a picture of my code:
.data
array: .space 100
i: .word 0
j: .word 0
temp: .word
.text
la $s2, i
la $s3, j
la $s4, temp
li $v0,5
syscall
move $s0, $v0 #array size
li $v0, 8
la $a0, array
li $a1, 100
move $s1, $a0 #actual array(with elements)
syscall
move $a0, $s0 #size becomes argument
move $a1, $s1 #array becomes argument
jal BubbleSort
li $v0, 4
move $a0, $v0
syscall
li $v0, 10
syscall
BubbleSort:
move $s0, $a0
move $s1, $a1
j ExternalLoop
ExternalLoop:
slt $t0,$s2, $s0 #for(i=0;I<N;i++)
beq $t0, $zero, ExitLoop
j InternalLoop
addi $s2, $s2,1 #i++
li $s3, 0 #reset j after every iteration
InternalLoop:
slt $t1, $s3, $s0 #for(j=0;J<N;j++)
beq $t1, $zero, ExitLoop
#array[j]=s1+4*j :
#sll $t2, $s3, 2
#add $s1, $s1, $t2
lb $t3, 0($s1) #array[j]
lb $t4, 4($s1) #array[j+1]
#swapping:
move $s4, $t3
move $t3, $t4
move $t4, $s4
sb $t5, 0($t3)
addi $s3, $s3, 1 #j++
j InternalLoop
move $v0, $t5
ExitLoop:
jr $ra
Maybe my mistake is somewhere at the end where I am storing the return values but I don't know. Can anyone help?
I have a MIPS programs with procedure that get two input strings as arguments and just concatenate them into one. I want to compare them and put the larger string into the smaller and print the full string length.
Here is the code that i have write till now:
.data
first: .space 255 #255 bytes for first string
second: .space 255 #255 bytes for second stringfull: .space 512 #255 bytes for first string
.text
main:
la $a0,first
li $a1,255
li $v0,8
syscall
la $a0,second
li $a1,255
li $v0,8
syscall
move $s0,$ra
la $a0,first
la $a1,second
la $a2,full
jal strcpy
move $ra,$s0
add $a0,$a1,$zero
li $v0, 1
syscall
#display a new-line
li $a0,10
li $v0,11
syscall
#exit
jr $ra
strcpy:
li $t8 10 #store newline in $t8
slt $s2,$a1,$a0
beq $s2,$zero,sCopyFirst
if_pocetok:
add $a3,$a1,$a0
add $a0,$a1,$zero
add $a1,$a3,$zero
beq $zero,$zero,sCopyFirst
#loop through first string and copy to output string
sCopyFirst:
lb $t0 0($a0)
beq $t0 $zero sCopySecond #exit loop on null byte
beq $t0 $t8 sCopySecond #exit loop on new-line
sb $t0 0($a2)
addi $a0 $a0 1
addi $a2 $a2 1
b sCopyFirst
#loop through second string and copy to output string
sCopySecond:
lb $t0 0($a1)
beq $t0 $zero sDone #exit on null byte
beq $t0 $t8 sDone #exit on new-line
sb $t0 0($a2)
addi $a1 $a1 1
addi $a2 $a2 1
b sCopySecond
sDone:
add $a1,$zero,$zero
sb $zero,0($a2) #null terminate string
addi $t1,$zero,0
loop:
lbu $t2, 0($a2)
beq $t2, $zero, exit
addi $a2, $a2, 1
addi $a1, $a1, 1
jal loop
exit:
jr $ra
I'm in the process of writing a program in MIPS that will determine whether or not a user entered string is a palindrome. It has three subroutines which are under construction.
Here is the main block of code, subroutines to follow with relevant info:
.data
Buffer: .asciiz " " # 80 bytes in Buffer
intro: .asciiz "Hello, please enter a string of up to 80 characters. I will then tell you if that string was a palindrome!"
.text
main:
li $v0, 4 # print_string call number
la $a0, intro # pointer to string in memory
syscall
li $v0, 8 #syscall code for reading string
la $a0, Buffer #save read string into buffer
li $a1, 80 #string is 80 bytes long
syscall
li $s0, 0 #i = 0
li $t0, 80 #max for i to reach
la $a0, Buffer
jal stripNonAlpha
li $v0, 4 # print_string call number
la $a0, Buffer # pointer to string in memory
syscall
li $s0, 0
jal findEnd
jal toUpperCase
li $v0, 4 # print_string call number
la $a0, Buffer # pointer to string in memory
syscall
Firstly, it's supposed to remove all non alpha-numeric characters from the string before hand, but when it encounters a character designated for removal, all characters after that are removed.
stripNonAlpha:
beq $s0, $t0, stripEnd #if i = 80 end
add $t4, $s0, $a0 #address of Buffer[i] in $t4
lb $s1, 0($t4) #load value of Buffer[i]
addi $s0, $s0, 1 #i = i + 1
slti $t1, $s1, 48 #if ascii code is less than 48
bne $t1, $zero, strip #remove ascii character
slti $t1, $s1, 58 #if ascii code is greater than 57
#and
slti $t2, $s1, 65 #if ascii code is less than 65
slt $t3, $t1, $t2
bne $t3, $zero, strip #remove ascii character
slti $t1, $s1, 91 #if ascii code is greater than 90
#and
slti $t2, $s1, 97 #if ascii code is less than 97
slt $t3, $t1, $t2
bne $t3, $zero, strip #remove ascii character
slti $t1, $s1, 123 #if ascii character is greater than 122
beq $t1, $zero, strip #remove ascii character
j stripNonAlpha #go to stripNonAlpha
strip:
#add $t5, $s0, $a0 #address of Buffer[i] in $t5
sb $0, 0($t4) #Buffer[i] = 0
#addi $s0, $s0, 1 #i = i + 1
j stripNonAlpha #go to stripNonAlpha
stripEnd:
la $a0, Buffer #save modified string into buffer
jr $ra #return
Secondly, it is supposed to convert all lowercase characters to uppercase.
toUpperCase:
beq $s0, $s2, upperEnd
add $t4, $s0, $a0
lb $s1, 0($t4)
addi $s1, $s1, 1
slti $t1, $s1, 97
#beq $t1, $zero, upper
slti $t2, $s1, 123
slt $t3, $t1, $t2
bne $t1, $zero, upper
j toUpperCase
upper:
add $t5, $s0, $a0
addi $t6, $t6, -32
sb $t6, 0($t5)
j toUpperCase
upperEnd:
la $a0, Buffer
jr $ra
The final subroutine, which checks if the string is a palindrome isn't anywhere near complete at the moment. I'm having trouble finding the end of the string because I'm not sure what PC-SPIM uses as the carriage return character.
Any help is appreciated, I have the feeling most of my problems result from something silly and stupid so feel free to point out anything, no matter how small.
Uh, this is a really old question, but the problem is that you're replacing the non-alphanumeric characters with a null character, which terminates the string at that point.
You can find out the value by doing something like this:
syscall to reading a string
mov first value to $2
check the value of $2 with PC-SPIM or a debugger