I have find a way to solve my exercise but my code has a bug... With some phrases works good, with other no... I explain better with 2 example:
- aaaaabc ---> the letter '' has the biggest number of occurences, is present time.
- hello world! ---> the letter 'l' has the biggest number of occurences, is present 3 times.
This is my code, maybe I have a problem on the control of the 'a' letter
.data
m1: .asciiz "Inserisci una stringa: "
m2: .asciiz "\nLa lettera '"
m3: .asciiz "' è quella con più occorrenze, cioè è presente "
m4: .asciiz " volte."
.align 2
myArray: .space 104 #Array di contatori
.text
.globl main
main:
#Stampo messaggio
li $v0, 4
la $a0, m1
syscall
#Alloco spazio per la stringa in ingresso
addi $sp, $sp, -256
#Salvo sp
move $s0, $sp
#Leggo una stringa fino all'invio
move $a0, $sp
li $a1, 255
li $v0, 8
syscall
#Passo parametri alla funzione
move $a0, $s0
#vado alla funzione
jal analizza_stringa
#Passo i parametri alla funzione
move $a0, $v0 #codice lettera
move $a1, $v1 #occorrenze
#vado alla funzione
jal stampa_risultato
end_program:
#Termino il programma
li $v0, 10
syscall
analizza_stringa:
#Faccio una copia di $a0 che servira per il loop
#piu interno mentre quello presente in a0
#serve per il loop piu esterno e dato che hanno due incrementi diversi
#ne uso due
move $t7, $s0
while_string:
# preleva un carattere (byte) dal messaggio
lb $t0, ($a0)
# N.B. la stringa (.asciiz) termina con "0"
beq $t0, $zero, check_best
#Se trova "invio" esce dal ciclo
beq $t0, 10, check_best
#Ricavo l'indice dell'array
subi $t3, $t0, 97
#Moltiplico per 4 perche ogni cella di memoria ha 4 byte
mul $t4, $t3, 4
#Sposto $s0(=a0 inizialmente) in un registro di appoggio altrimenti
#mi altera le iterazioni per il primo loop
move $t6, $t7
while_occorrenza:
#quando finisce la stringa esci dal ciclo
beq $t1, 10, continue
#prelevo dallo stack un dato
lb $t1,($t6)
#Controllo l'occorrenza
bne $t1, $t0, continue2
#Conto occorrenza
addi $t5, $t5, 1
continue2:
#Incrementare il puntatore alla stringa
addi $t6, $t6, 1
#Ripeto
j while_occorrenza
continue:
#Metto il dato nella posizone calcolata
sw $t5, myArray($t4)
#Azzero t5
li $t5, 0
#Azzero t3
li $t3, 0
#Azzero t1
li $t1, 0
# punta al carattere successivo
addi $a0, $a0, 1
# ripeti il ciclo
j while_string
check_best:
#inizializzo t0
li $t0, 0
#Carico il primo valore
lw $t1, myArray($t0)
#Incremento il puntatore all'array
addi $t0, $t0, 4
while_check_best:
#Quando t0 ha visitato tutto l'array, esce
beq $t0, 104, exit_check
#contatore per ottenere la lettera
addi $t5, $t5, 1
#Carico in t4 il numero in t0
lw $t4, myArray($t0)
#Effettuo il controllo sui caratteri ---> ex bgt
bge $t4, $t1, scambia #se t1>t4 non fai nulla
#Ripeto il giro
j continue_check
scambia:
#Controllo adesso, se la lettera letta
#ha un numero di occorrenze maggiore di
#quella che ho gia salvato in t2 (cioe letta prima)
blt $t4, $t2, continue_check
#Contiene il carattere letto nel ciclo
#che è piu grande di quello letto fuori
#dal ciclo
move $t2, $t4
#calcolo lettera
add $t3, $t5, 97
continue_check:
#Incremento il puntatore dell'array
addi $t0, $t0, 4
#Ripeto
j while_check_best
exit_check:
#Passo per convenzione al chiamante il codice della lettera
move $v0, $t3
#ed il numero delle occorrenze
move $v1, $t2
#ritorno al chiamante
jr $ra
stampa_risultato:
#Salvo il codice ascii della lettera
#ottenuta
move $t0, $a0
#Stampo il primo messaggio
li $v0, 4
la $a0, m2
syscall
#Stampo la lettera tramite codice ascii
li $v0, 11
move $a0, $t0
syscall
#Stampo il secondo messaggio
li $v0, 4
la $a0, m3
syscall
#Stampo numero di occorrenze
li $v0, 1
move $a0, $a1 #recupero il dato passato alla funzione in a1
syscall
#Stampo ultimo messaggio
li $v0, 4
la $a0, m4
syscall
#ritorno al chiamante
jr $ra
for any other explaination, can read me under this post. Thank you very much at all.
EDIT: maybe the problem is really on the 'a' letter if it is the problem because if I try with 'a' I haven't results (first point in the description), with all the other letters yes (second point in the description)