![]() |
Show 150 posts per page |
.dsy:it. (http://www.dsy.it/forum/)
- Architettura degli elaboratori e delle reti (http://www.dsy.it/forum/forumdisplay.php?forumid=210)
-- [HELP on MIPS] lettura e comparazione stringhe (http://www.dsy.it/forum/showthread.php?threadid=25570)
[HELP on MIPS] lettura e comparazione stringhe
Ciao a tutti!
sto facendo un programmino in assembler x il MIPS e voglio chiedere all'utente se vuole ricominciare o terminare.
Mi aspetto un carattere:
se scrive 'y' ricomincio
se scrive 'n' mi fermo
se scrive altro glielo richiedo.
Riesco a leggere l'input ma poi non riesco a fare il confronto con i caratteri 'y' e 'n' per fare i relativi salti.
Qcuno mi aiuta?
Questo e' il codice che ho scritto relativamente a questo problema:
nella sezione .data:
code:
repeat: .asciiz "\nWant to do it again?\n" answer: .asciiz "" yes: .ascii "y" no: .ascii "n"
code:
# chiede se ricominciare (main) o finire (exit) final: # stampa stringa di richiesta ripetizione programma la $a0, repeat li $v0, 4 syscall j again again: # legge risposta da input la $a0, answer # sara' solo y o n, non null terminated li $a1, 2 # quindi 1 solo byte e' sufficiente li $v0, 8 syscall # controlla la risposta la $t2, yes la $t3, no beq $a0, $t2, main # se la risposta e' y, allora ripeti da (main) beq $a0, $t3, exit # se la risposta e' n, allora esci dal programma (exit) j again # se la risposta e' altro, richiedi (again) # esce dal programma exit: li $v0, 10 syscall
code:
main: # Start of code section # svuoto i registri temporanei li $t0, 0 li $t2, 0 li $t3, 0
__________________
*** Proposta di legge di iniziativa popolare: "8x1000 ALLA RICERCA"
Informati e firma la petizione! E' nel tuo interesse! ![]()
*** Browse my dA gallery !
***In medio stat virtus
può dipendere dal fatto che qundo l'utente digita "y" o "n" in realtà viene memorizzato "y/0" e n"/0" (ora nn ricordo se era slash o backslash...)...perchè se nn ricordo male .asciiz mette automaticamente il carattere di terminazione alla fine, .ascii normale no......quindi quando confronti la risposta con yes e no confronti ad esempio yes(= "y") con "y/0" quindi è false
E' solo un 'idea......probabilmente sbaglio...al max prova, se ho ragione tanto meglio!
ci ho provato, ma non trovo la combinazione giusta...
mi interesserebbe capire la teoria a monte per non tirare a caso, ma qcosa di sintetico e chiaro...
non trovo nemmeno esempi di codice che trattino stringhe/caratteri... 
l'altra idea, oltre al carattere terminatore, potrebbe essere che passo indirizzo anziche' valore o viceversa, ma anche qui non mi e' troppo chiaro come lavori...
__________________
*** Proposta di legge di iniziativa popolare: "8x1000 ALLA RICERCA"
Informati e firma la petizione! E' nel tuo interesse! ![]()
*** Browse my dA gallery !
***In medio stat virtus
alla fine, con grande pazienza del mio moroso, siamo riusciti a sistemare il codice... 
in definitiva bisogna usare lb quando si vuol leggere un solo carattere e lasciare una dimensione di 3 quando leggo in input.
posto il codice completo corretto e funzionante (magari non e' ottimale ma puo' servire da spunto...
):
code:
# FATTORIALE .globl main .data # Data declaration section inputstr: .asciiz "\nInserire un numero:\n" error: .asciiz "\nErrore: inserire un numero positivo.\n" outputstr: .asciiz "\nRisultato: " repeat: .asciiz "\n\nWant to do it again?\n" ansbuffer: .space 3 yes: .byte 0x79 # =y no: .byte 0x6e # =n .text # legge un intero e lo mette in $v0 e ritorna al codice chiamante leggiint: li $v0, 5 syscall jr $ra # stampa un intero da $a0 e ritorna al codice chiamante stampaint: li $v0, 1 syscall jr $ra # stampa una stringa da $a0 e ritorna al codice chiamante stampastr: li $v0, 4 syscall jr $ra # chiede se ricominciare (main) o finire (exit) final: # stampa stringa di richiesta ripetizione programma la $a0, repeat li $v0, 4 syscall # j again #again: # legge risposta da input la $a0, ansbuffer # sara' solo y o n, non null terminated li $a1, 3 # quindi 1 solo byte e' sufficiente li $v0, 8 syscall # controlla la risposta lb $t0, ansbuffer lb $t1, yes lb $t2, no beq $t0, $t1, main # se la risposta e' y, allora ripeti da (main) beq $t0, $t2, exit # se la risposta e' n, allora esci dal programma (exit) j final # se la risposta e' altro, richiedi (again) # esce dal programma exit: li $v0, 10 syscall # controlla se $t0 e' minore/uguale/maggiore di zero e salta alla relativa label check: bltz $t0, inputneg beqz $t0, inputzero bgtz $t0, inputpos # arriva qui dalla check # se il numero passato in input e' NEGATIVO # stampa un messaggio d'errore e richiede i dati in input inputneg: la $a0, error jal stampastr j asknum # arriva qui dalla check # se il numero passato in input e' ZERO # il risultato (1) e' gia' in $t1 quindi chiama la procedura che lo stampa ed esce inputzero: la $a0, outputstr jal stampastr j printres # arriva qui dalla check # se il numero passato in input e' POSITIVO # calcola ricorsivamente il risultato # mette il risultato in $t1 e chiama la procedura che lo stampa ed esce inputpos: # moltiplico il numero attuale ($t0) con il risultato parziale ($t1) # lo metto in $t1 come nuovo risultato parziale mulou $t1, $t0, $t1 # decremento il numero attuale ($t0) addi $t0, $t0, -1 # chiamata ricorsiva alla check j check # stampa il risultato dal registro $t1 ed esce printres: move $a0, $t1 li $v0, 1 jal stampaint j final main: # Start of code section # svuoto i registri temporanei li $t0, 0 li $t1, 0 li $t2, 0 # chiede il numero in input e lo memorizza in $t0 asknum: la $a0, inputstr jal stampastr jal leggiint move $t0, $v0 # inizia il calcolo del fattoriale del numero calculate: # inizializza $t1 a 1 li $t1, 1 # controlla se il numero e' minore/uguale/maggiore di zero # la check poi a seconda del valore manda alla procedura corretta da eseguire j check # END OF PROGRAM
__________________
*** Proposta di legge di iniziativa popolare: "8x1000 ALLA RICERCA"
Informati e firma la petizione! E' nel tuo interesse! ![]()
*** Browse my dA gallery !
***In medio stat virtus
Forse ti puo' aiutare ![]()
![]()
![]()
![]()
. Ciao
.data
szNewNumber: .asciiz "Vuoi continuare (s/S/y/Y) ? "
szYesChars: .asciiz "sSyY"
.text
main:
MainLoop:
la $a0, szNewNumber # chiedo all'utente se vuole calcolare un altro numero
la $a1, szYesChars
jal ReadYes
beq $v0, 1, MainLoop # continuo il programma se la funzione ReadYes ha restituito 1
##################################################
###########################
#
# int ReadYes(const char* promptMessage, const char* yesChars)
#
# Descrizione:
# Legge un carattere da tastiera verificando che sia uguale a uno dei
# caratteri referenziati dal registro $a1
#
# Registri utilizzati:
# $a0 = indirizzo della stringa da stampare
# $a1 = indirizzo della stringa di caratteri accettati come risposta positiva
# $v0 = valore di ritorno, $v0 = 1 se il carattere inserito e' uguale a uno
# dei caratteri della stringa referenziata da $a1 altrimenti $v0 = 0
#
##################################################
###########################
ReadYes:
addi $sp, $sp, -16 # alloco spazio nello stack (4 words * 4 bytes ciascuna = 12)
sw $ra, 0($sp) # memorizzo l'indirizzo di ritorno $ra nello stack
sw $a0, 4($sp) # memorizzo il registro $a0 nello stack
sw $a1, 8($sp) # memorizzo il registro $a1 nello stack
sw $zero, 12($sp) # azzero i 4 byte che utilizzo come buffer temporaneo
li $v0, 4 # stampo la stringa puntata da $a0
lw $a0, 4($sp) # recupero il valore di $a0 dallo stack
syscall
li $v0, 8 # leggo una stringa e la memorizzo in un buffer allocato nello stack
addi $a0, $sp, 12 # il buffer si trova nel record di attivazione a partire da $sp+12
li $a1, 2 # dimensione del buffer compreso lo zero finale (leggo solo un carattere)
syscall
li $v0, 4 # stampo un carriage return
la $a0, szCharCR
syscall
lb $t0, 12($sp) # leggo il primo byte del buffer e lo memorizzo in $t0
lw $t1, 8($sp) # recupero il valore di $a1 dallo stack e lo memorizzo in $t1
ReadYes_loop:
lbu $t2, 0($t1) # memorizzo in $t2 il primo byte referenziato da $t1 (stringa caratteri accettati)
bnez $t2, ReadYes_c1 # se il valore e' diverso da zero (fine stringa) continuo la funzione
li $v0, 0 # altrimenti termino la funzione restituendo 0
j ReadYes_ret
ReadYes_c1:
bne $t2, $t0, ReadYes_c2 # se il valore e' diverso da $t0 continuo la funzione
li $v0, 1 # altrimenti termino la funzione restituendo 1
j ReadYes_ret
ReadYes_c2:
addi $t1, $t1,1 # incremento $t1, il puntatore alla stringa di caratteri accettati
j ReadYes_loop
ReadYes_ret:
lw $a1, 8($sp) # ripristino il registro $a1
lw $a0, 4($sp) # ripristino il registro $a0
lw $ra, 0($sp) # ripristino il registro $ra
addi $sp, $sp, 16 # ripristino il valore iniziale dello stack pointer
jr $ra
| All times are GMT. The time now is 17:05. | Show all 5 posts from this thread on one page |
Powered by: vBulletin Version 2.3.1
Copyright © Jelsoft Enterprises Limited 2000 - 2002.