// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Genera numeros primos
// * Autor: Roldan Castro Luis Alberto
// * Fecha: 07-04-2025
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/bMg5LblZenRBmLIoOkPX8nqH0
// ****************************************************************************
// ****************************************************************************
// Version de Python
//
//def es_primo(n):
// if n < 2:
// return False
// if n in (2, 3):
// return True
// if n % 2 == 0 or n % 3 == 0:
// return False
// i = 5
// while i * i <= n:
// if n % i == 0 or n % (i + 2) == 0:
// return False
// i += 6
// return True
//
//def generar_primos(cantidad):
// primos = []
// num = 2
// while len(primos) < cantidad:
// if es_primo(num):
// primos.append(num)
// num += 1
// return primos
//
//# Solicitar la cantidad de primos al usuario
//cantidad = int(input("¿Cuántos números primos quieres generar? "))
//primos_generados = generar_primos(cantidad)
//print("Números primos generados:", primos_generados)
// ****************************************************************************
.data
msg_prompt: .asciz "Ingrese cantidad de primos a generar: "
len_prompt = . - msg_prompt
msg_prime: .asciz "Primo #"
len_prime = . - msg_prime
msg_colon: .asciz ": "
len_colon = . - msg_colon
msg_newline: .asciz "\n"
len_newline = . - msg_newline
buffer: .fill 32, 1, 0 // Buffer para conversión numérica
.text
.global _start
.align 2
_start:
// Mostrar mensaje inicial
mov x0, #1
adr x1, msg_prompt
mov x2, len_prompt
mov x8, #64 // syscall write
svc #0
// Leer entrada del usuario (número de primos a generar)
mov x0, #0 // stdin
adr x1, buffer // buffer para almacenar entrada
mov x2, #12 // longitud máxima a leer
mov x8, #63 // syscall read
svc #0
// Convertir ASCII a número (x19 = cantidad de primos)
mov x19, #0 // inicializar contador
adr x20, buffer // dirección del buffer
mov x21, #10 // base decimal
convert_loop:
ldrb w22, [x20], #1 // cargar byte y avanzar puntero
cmp w22, #0xA // verificar si es newline
beq convert_done
sub w22, w22, #'0' // convertir ASCII a dígito
madd x19, x19, x21, x22 // x19 = x19 * 10 + dígito
b convert_loop
convert_done:
// Inicializar variables para generación de primos
mov x23, #2 // primer número primo
mov x24, #0 // contador de primos encontrados
prime_loop:
// Verificar si es primo (x23 = número a verificar)
mov x25, #2 // divisor inicial
check_prime:
cmp x25, x23 // si divisor >= número, es primo
bge is_prime
udiv x26, x23, x25 // x26 = x23 / x25
msub x27, x26, x25, x23 // x27 = resto
cbz x27, not_prime // si resto == 0, no es primo
add x25, x25, #1 // incrementar divisor
b check_prime
is_prime:
// Mostrar el número primo encontrado
add x24, x24, #1 // incrementar contador de primos
// Mostrar "Primo #"
mov x0, #1
adr x1, msg_prime
mov x2, len_prime
mov x8, #64
svc #0
// Mostrar número de secuencia
mov x0, x24
bl print_number
// Mostrar ": "
mov x0, #1
adr x1, msg_colon
mov x2, len_colon
mov x8, #64
svc #0
// Mostrar número primo
mov x0, x23
bl print_number
// Mostrar nueva línea
mov x0, #1
adr x1, msg_newline
mov x2, len_newline
mov x8, #64
svc #0
// Verificar si hemos encontrado suficientes primos
cmp x24, x19
bge exit_program
not_prime:
add x23, x23, #1 // probar siguiente número
b prime_loop
exit_program:
// Salir del programa
mov x0, #0 // código de salida 0
mov x8, #93 // syscall exit
svc #0
// Función para imprimir número (x0 = número a imprimir)
print_number:
stp x29, x30, [sp, -16]!
mov x29, sp
adr x1, buffer + 31 // apuntar al final del buffer
mov w2, #0 // terminador nulo
mov x3, #10 // base decimal
convert_to_ascii:
udiv x4, x0, x3 // x4 = cociente
msub x5, x4, x3, x0 // x5 = resto (dígito)
add x5, x5, #'0' // convertir a ASCII
strb w5, [x1], #-1 // almacenar y retroceder
mov x0, x4 // actualizar cociente
cbnz x0, convert_to_ascii // continuar si cociente != 0
// Calcular longitud
adr x2, buffer + 31
sub x2, x2, x1
add x2, x2, #1
// Imprimir número
add x1, x1, #1 // ajustar puntero al inicio
mov x0, #1 // stdout
mov x8, #64 // syscall write
svc #0
ldp x29, x30, [sp], 16
ret