Calcular los n primeros números primos en MIPS

Programa que calcula los n primeros primos, siendo n un número introducido por el usuario. Además si el número introducido es negativo salta una excepción.


.data
.globl main
cad: .asciiz "Introduce un numero n positivo: "
ng: .asciiz "El numero es negativo\n"
cad2: .asciiz "Calcular los n primeros numeros primos.\n"
espaciado: .asciiz " "
.text
main:

#no usar las cad directamrnte, cambiar


li $v0, 4 #Llamada al sistema para imprimir la cadena indicada
la $a0, cad2 # por el puntero $a0
syscall
cont: li $v0, 4 #Llamada al sistema para imprimir la cadena indicada
la $a0, cad # por el puntero $a0
syscall

li $v0, 5 #Llamada al sistema para leer un nÂœmero
syscall
move $t0, $v0 # mueves el numero de v0 a t0
jal negativo
li $a1, 1 #iniciamos un contador, saber si es primo o no
li $a2, 0 #iniciamos un contador, saber si es primo o no
li $a3, 1 #numero qu va desde el uno hasta infinito
##########
li $t7, 0 #contador del numero de numeros que hay que imprimir
##########
j numero #pasa al numero
negativo:
move $t6, $t0 #mover el numero introducido a t6
bltz $t6, negar
jr $ra

negar: li $v0, 4 #Llamada al sistema para imprimir la cadena indicada
la $a0, ng # por el puntero $a0
syscall
j cont

numero:
beq $t0, $t7, final #si ya se han imprimido los n numeros, acaba el programa
jal subrutina1 #calcula si el numero es primo o no, el numero que usa es el que hay en $a3
beq $v0, 1, imprimir1 #si es uno(primo) l impirime, si no le suma uno y continua el bucle
addi $a3,$a3,1 #pasa al siguiente numero para calcular si es primo o no
j numero#vuelve a empezar

imprimir1:
li $v0,1 #imprime  el numero
la $a0, ($a3) #mover el numero a $a0 para imprimirlo
syscall
la $a0, espaciado #ponemos un espacio entre los numeros que imprimes
li $v0, 4 #Llamada al sistema que imprime la cadena
syscall
addi $t7, $t7,1 #si se ha imprimido un primo, se le suma uno a t7, para que cuando llegue a los n numeros acabe el programa
addi $a3,$a3,1 #pasa al siguiente numero para calcular si es primo o no
j numero # vuelvee a empezar

final: #acaba el programa
li $v0,10 #fin
syscall

#mira si es primo o no, devuelve 1 si es primo y cero si no lo es
subrutina1:#devuelve v0
addi $sp, $sp, -4 #resta cuatro a la pila
sw $ra, ($sp)#guarda $ra en la pila, para despues con el jr volver a la funcion numero, y no perder el valor de donde hay que volver
jal subrutina_2 # vas a la subrutina dos, que es la que calcual en si si es primo o no
#te va a devolver un numero mayor de 1 si no es primo y uno si si lo es
beq $v0, 1, esp #si es primo devuelve un uno, con la funcion esp
li $v0, 0#si no , devuelve 0
j fins1# y salta a fins1
esp:
li $v0, 1
#devuelve el uno y "salta"(sigue) a fins1
fins1: #volver al numero
lw $ra, ($sp)#coges el $ra
addi $sp, $sp, 4#actualizas la pila
jr $ra # volvemos al numero
subrutina_2:
beq $a3, $a1, fin#si el numero que va aumentando es igual al comparado(a3), acaba
div $a3,$a1 #divides el numero a3 entre a1, que va aumentando de uno en uno
mfhi $t2 #coges el resto y lo mueves a t0
beqz $t2, etiqueta # si vale 0 etiqueta, por lo que $a1 divide a $a3, por lo que o $a1 es el uno, o el numero no es primo
addi $a1, $a1, 1 #si no vale cero, como no divide a $a3, le sumas uno al contador que divide a $a3
j subrutina_2  #vuelves al bucle
etiqueta:
addi $a1, $a1, 1 #aumentas el conrador para dividir $a3 por el siguiente numero
addi $a2, $a2, 1 #Si  es  0, con lo que incrementamos el contador de numeros que dividen a $a3
j subrutina_2 #vuelves al bucle

fin: #volver a subrutina1
move $v0, $a2 #mueves el resultado que te da en $a2, que es la cantidad de numeros que dividen al $a3, a $v0
li $a1, 1 #ponemos en contador a cero
li $a2, 0 #ponemos en contador a cero
jr $ra # volvemos a subritina1