# Stampa i nomi delle cifre dell’intero
.data
string0: .asciiz "Inserire un numero intero positivo\n\n"
#string1: .asciiz "Input non valido\n\n"
scase0: .asciiz "Zero "
scase1: .asciiz "Uno "
scase2: .asciiz "Due "
scase3: .asciiz "Tre "
scase4: .asciiz "Quattro "
scase5: .asciiz "Cinque "
scase6: .asciiz "Sei "
scase7: .asciiz "Sette "
scase8: .asciiz "Otto "
scase9: .asciiz "Nove "
.align 2
jump_table: .space 16 # jump table array a 4 word che verra' instanziata dal main con gli indirizzi delle label che chiameranno le corrispondenti procedure
.text
.globl main
main:
# prepara la jump_table con gli indirizzi delle case actions
la $s1, jump_table #salvo l'indirizzo iniziale della jump table
la $t0, case0
sw $t0, 0($s1)
la $t0, case1
sw $t0, 4($s1)
la $t0, case2
sw $t0, 8($s1)
la $t0, case3
sw $t0, 12($s1)
la $t0, case4
sw $t0, 16($s1)
la $t0, case5
sw $t0, 20($s1)
la $t0, case6
sw $t0, 24($s1)
la $t0, case7
sw $t0, 28($s1)
la $t0, case8
sw $t0, 32($s1)
la $t0, case9
sw $t0, 36($s1)
li $v0,4
la $a0,string0 # prompt
syscall
li $v0,5 # $v0 = read_int
syscall
blez $v0,ending # Se l'intero è non positivo salta alla terminazione del programma
move $a0,$v0 # imposta i parametri per la chiamata della procedura
move $a1,$s1
jal stamp # chiama fattoriale
li $v0,10 # esce
syscall
# procedura che stampa i nomi delle cifre dell’intero letto, delimitati esattamente da uno spazio.
# Esempio, “728”, l’uscita dovrà essere “Sette Due Otto”.
stamp: # procedura
addi $sp,$sp,-8 # crea spazio per due words nello stack frame
sw $ra,4($sp) # salva l'indirizzo di ritorno al chiamante
sw $a0,0($sp) # salva il parametro d'invocazione (intero letto da tastiera)
bgtz $a0,L1 # se $a0 > 0 salta a L1
addi $sp,$sp,8 # ripristina lo stack frame
jr $ra # ritorna al chiamante
# Ricorsivamente estrae le varie cifre dell'intero e le stampa a video in lettere
L1: # n >= 1
li $s0,10
div $a0,$s0 # mette in registri speciali quoziente e resto della divisione per 10
mfhi $t0 # mette il resto in $t0
mflo $a0 # mette il quoziente in $a0 cioè le cifre rimanenti ancora da analizzare
jal stamp # chiamata ricorsiva a stamp sulle cifre rimanenti
add $t0, $t0, $t0
add $t0, $t0, $t0 # ho calcolato (scelta-1) * 4
add $t0, $t0, $a1 # sommo all'indirizzo della prima case action l'offset calcolato sopra
lw $t0, 0($t0) # $t0 = indirizzo a cui devo saltare
j $t0
lw $a0,0($sp) # ripristina i valori salvati in precedenza nello stack frame: parametro e indirizzo di ritorno
lw $ra,4($sp)
addi $sp,$sp,8 # ripristina lo stack frame
jr $ra # ritorna al chiamante
syscall
# Stampa un messaggio di errore e termina
ending:
# li $v0,4
# la $a0,string1 # messaggio di errore
# syscall
li $v0,10 # esce
syscall
case0:
la $a0,scase0
j print
case1:
la $a0,scase1
j print
case2:
la $a0,scase2
j print
case3:
la $a0,scase3
j print
case4:
la $a0,scase4
j print
case5:
la $a0,scase5
j print
case6:
la $a0,scase6
j print
case7:
la $a0,scase7
j print
case8:
la $a0,scase8
j print
case9:
la $a0,scase9
j print
print:
li $v0,4
syscall
lw $a0,0($sp) # ripristina i valori salvati in precedenza nello stack frame: parametro e indirizzo di ritorno
lw $ra,4($sp)
addi $sp,$sp,8 # ripristina lo stack frame
jr $ra # ritorna al chiamante
Se si prova a avviarlo sembra partire bene e funzionare ma si blocca da quello che mi pare di capire sull'istruzione jr $ra secondo voi cosa sbaglio?
Bad Address in Data/Stack read
Bad Address in Text... etc...
Che diavolo?