# Il programma determina i numeri primi costituenti un intero N.
# Per semplicita' i numeri primi vengono dati in un vettore.

.data
prompt: .asciiz "Inserire un numero intero: "
output: .asciiz "I numeri primi sono: "
primes_test: .word 1 2 3 5 7 11 13 17 19 23
primes: .space 40
spazio: .asciiz " "
        .text
        .globl main

# $s0 ($a0) contiene il numero di numeri primi da testare.
# $s1 ($a1) contiene l’indirizzo del vettore dei numeri primi da testare
# $s2 ($a2) contiene N, il numero primo da scomporre
# $s3 ($a3) contiene l’indirizzo del vettore dei numeri primi di N
# $s4 ($v0) contiene il numero di numeri primi di N
main:
	li $s0, 40		# Deve essere impostato uguale alla lunghezza 
				# di primes_test (in byte)
	la $s1, primes_test       

	li $v0, 4
      la $a0, prompt
      syscall		# stampa prompt

	li $v0, 5
      syscall		# legge l’intero N
	move $s2, $v0

	la $s3, primes		
			 	
	move $a0, $s0	# prepara la chiamata
	move $a1, $s1	# prepara la chiamata
	move $a2, $s2	# prepara la chiamata
	move $a3, $s3	# prepara la chiamata
	jal find_primes
	move $s4, $v0 	# Dimensione in byte dei numeri primi trovati 	

# Scrivo anche il numero 1 come primo costituendo di N	
	lw $t0, 0($s1) 	
	add  $t1, $s4, $s3
	sw $t0, 0($t1)		
	addi $s4, $s4, 4		# punto al nuovo elemento in primes
	
# stampa il risultato ed esci
	li $v0, 4
	la $a0, output
	syscall

	move $t0, $s3
	add $t1, $s4, $t0 
Loop_w:	 
	 beq $t0, $t1, fine

	li $v0, 4		# Stampa uno spazio
	la $a0, spazio
	syscall

 	 lw $a0, 0($t0)
	 li $v0, 1
       syscall
	 addi $t0, $t0, 4
	 j Loop_w
fine:	 
        li $v0, 10
        syscall
 
find_primes:
	addi $sp, $sp, -8
	sw $a0, 4($sp)
	sw $ra, 0($sp)

	li $t6, 0	

	move $v0, $zero		# memorizza lo spazio in byte occupato
					# dai numeri primi trovati
	addi $a0, $a0, -4	
	jal find_first_prime

	lw $ra, 0($sp)
	lw $a0, 4($sp)
	addi $sp, $sp, 8
	jr $ra

find_first_prime:
	addi $sp, $sp, -4
	sw $ra, 0($sp)
	beq $a0, $zero, fine_1	# il ciclo termina quando ci si posiziona sul 
					# primo elemento di primes_test (cioe' base + 4)
					# (primo elemento di prime_test che e' = 1)
	add $t0, $a1, $a0
	lw $t2, 0($t0)		# estraggo il numero primo da testare
	addi $a0, $a0, -4		# mi posiziono sul numero primo successivo da 
				# esaminare
	rem $t3, $a2, $t2		# guardo se $t2 e' un divisore di N	
	bgtz $t3, oltre		# se non e' un divisore di N, passo al successivo
				# numero primo da esaminare
	div $a2, $a2, $t2		# divido N per il numero primo trovato	
	add  $t4, $v0, $a3 	# $t4 indirizzo su primes in cui scrivere
	sw $t2, 0($t4)		# memorizzo il numero primo trovato
	addi $v0, $v0, 4		# punto al nuovo elemento in primes
oltre:
	jal find_first_prime
fine_1:	

	lw $ra, 0($sp)
	addi $sp, $sp, 4
	jr $ra
 	

	

