Programa 30: Generador de números primos hasta n número en Assembly ARM64 - Alejandro Suarez
by pepinisillo
GNU/Linux
•
xterm
•
bash
92 views
📌 Demostración: Generador de números primos hasta n número en ARM64 Assembly
💻 Lenguajes de Interfaz en TECNM Campus ITT
👨💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/09
🎯 Descripción
Este programa genera números primos hasta n número y los muestra en la terminal.
La implementación se realiza en:
✅ Assembly ARM64 para RaspbianOS en Raspberry Pi
🔧 Compilación en Raspberry Pi (ARM64)
as generador-primos.s -o generador-primos.o
ld generador-primos.o -o generador-primos
▶️ Ejecución
./generador-primos
👀 Código fuente
🔗 Código fuente en Gist: Programa 30 Generador de numeros primos hasta n numero Código Assembly ARM64 para RaspbianOS
/*
______ ____ ____ __ __
/\ _ \/\ _`\ /'\_/`\ /'___\/\ \\ \
\ \ \L\ \ \ \L\ \/\ \/\ \__/\ \ \\ \
\ \ __ \ \ , /\ \ \__\ \ \ _``\ \ \\ \_
\ \ \/\ \ \ \\ \\ \ \_/\ \ \ \L\ \ \__ ,__\
\ \_\ \_\ \_\ \_\ \_\\ \_\ \____/\/_/\_\_/
\/_/\/_/\/_/\/ /\/_/ \/_/\/___/ \/_/
♡ ∩_∩
(„• ֊ •„)♡
| ̄U U ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
| • Lenguajes de Interfaz en TECNM Campus ITT |
| • Autor: Alejandro Suarez Sandoval |
| • Fecha: 2025/04/09 |
| • Descripción: Programa que genera numeros primos hasta n |
| numero en Ruby y Assembly ARM64 para RaspbianOS. |
| • Demostración: |
| https://asciinema.org/a/713735 |
| • Compilación (Raspberry Pi ARM64): |
| as generador_primos.s -o generador_primos.o |
| ld generador_primos.o -o generador_primos |
| • Ejecución: ./generador_primos |
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje Ruby •°•═══════
def es_primo?(numero)
return false if numero <= 1
return true if numero <= 3
return false if numero % 2 == 0 || numero % 3 == 0
i = 5
w = 2
while i * i <= numero
return false if numero % i == 0
i += w
w = 6 - w
end
true
end
def encontrar_primos_hasta(n)
(2..n).select { |num| es_primo?(num) }
end
n = 100
puts "Números primos hasta #{n}:"
primos = encontrar_primos_hasta(n)
puts primos.join(' ')
════════════════════•°• ☆ •°•══════════════════════════════
/*
/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */
.global _start // Punto de entrada global
.data
// Valor máximo hasta el que buscar números primos
n_value:
.word 100 // Buscar primos hasta este número
// Mensajes
msg_intro:
.ascii "Números primos hasta "
msg_intro_len = . - msg_intro
msg_colon:
.ascii ":\n"
msg_colon_len = . - msg_colon
space:
.ascii " "
space_len = . - space
newline:
.ascii "\n"
newline_len = . - newline
// Búfer para convertir números a texto
buffer:
.skip 20
.text
_start:
// Cargar el valor N
adr x19, n_value
ldr w19, [x19] // w19 = valor máximo N
// Mostrar mensaje introductorio
mov x0, #1 // stdout
adr x1, msg_intro
mov x2, #msg_intro_len
mov x8, #64 // syscall write
svc #0
// Mostrar el valor N
mov x24, x19
bl num_to_ascii
// Mostrar dos puntos y nueva línea
mov x0, #1
adr x1, msg_colon
mov x2, #msg_colon_len
mov x8, #64
svc #0
// Empezar a generar primos desde 2
mov w20, #2 // w20 = contador actual (comienza en 2)
prime_loop:
// Si contador > N, termina
cmp w20, w19
b.gt end_prime_loop
// Verificar si el número actual es primo
mov x24, x20 // Pasar número actual como parámetro
bl is_prime
// Si w0 = 1, el número es primo, mostrarlo
cmp w0, #1
b.ne not_prime
// Es primo, mostrar número
mov x24, x20
bl num_to_ascii
// Mostrar espacio
mov x0, #1
adr x1, space
mov x2, #space_len
mov x8, #64
svc #0
not_prime:
// Incrementar contador y continuar
add w20, w20, #1
b prime_loop
end_prime_loop:
// Mostrar nueva línea final
mov x0, #1
adr x1, newline
mov x2, #newline_len
mov x8, #64
svc #0
// Salir del programa
mov x0, #0
mov x8, #93 // syscall exit
svc #0
// Subrutina para verificar si un número es primo
// Entrada: x24 = número a verificar
// Salida: w0 = 1 si es primo, 0 si no lo es
is_prime:
// Si el número es <= 1, no es primo
cmp w24, #1
b.le not_prime_ret
// Si el número es 2 o 3, es primo
cmp w24, #3
b.le is_prime_ret
// Verificar si es divisible por 2
and w0, w24, #1 // w0 = n % 2
cmp w0, #0
b.eq not_prime_ret // Si es par (excepto 2), no es primo
// Comprobar divisibilidad desde 3 hasta sqrt(n) en pasos de 2
mov w21, #3 // w21 = divisor de prueba
check_divisibility:
// Calcular aproximadamente si divisor > sqrt(n)
mul w22, w21, w21 // w22 = divisor^2
cmp w22, w24 // Comparar con n
b.gt is_prime_ret // Si divisor^2 > n, es primo
// Comprobar si n es divisible por el divisor actual
sdiv w22, w24, w21 // w22 = n / divisor
mul w22, w22, w21 // w22 = (n / divisor) * divisor
cmp w22, w24 // Si w22 == w24, entonces n es divisible por divisor
b.eq not_prime_ret // No es primo
// Incrementar divisor en 2 y comprobar siguiente
add w21, w21, #2
b check_divisibility
is_prime_ret:
mov w0, #1 // Es primo
ret
not_prime_ret:
mov w0, #0 // No es primo
ret
// Subrutina para convertir número a ASCII y mostrarlo
num_to_ascii:
// Preparar para convertir el número a texto
mov x25, x24 // Copiar número a x25
adr x26, buffer // x26 = puntero al búfer
add x26, x26, #19 // Empezar desde el final del búfer
mov x27, #10 // x27 = base 10 para división
// Caso especial si el número es 0
cbnz x25, convert_loop
mov w28, '0' // Carácter ASCII '0'
strb w28, [x26]
sub x26, x26, #1
b end_convert
convert_loop:
// Comprobar si el número es 0
cbz x25, end_convert
// Obtener el último dígito (número % 10)
udiv x28, x25, x27 // x28 = x25 / 10
msub x29, x28, x27, x25 // x29 = x25 - (x28 * 10) = x25 % 10
// Convertir dígito a ASCII y guardarlo
add w29, w29, #'0' // Convertir a carácter ASCII
strb w29, [x26] // Guardar en búfer
sub x26, x26, #1 // Mover puntero
// Actualizar número para siguiente iteración
mov x25, x28 // Número = número / 10
b convert_loop
end_convert:
// Calcular longitud de la cadena resultante
add x26, x26, #1 // Ajustar puntero al primer dígito
adr x25, buffer
add x25, x25, #20
sub x2, x25, x26 // x2 = longitud de la cadena
// Imprimir número
mov x0, #1 // File descriptor: 1 para stdout
mov x1, x26 // Dirección del búfer
mov x8, #64 // Syscall número 64: write
svc #0 // Llamada al sistema
ret