GNU/Linux
•
xterm
•
bash
85 views
📌 Demostración: Verificador de números primos en ARM64 Assembly
💻 Lenguajes de Interfaz en TECNM Campus ITT
👨💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/08
🎯 Descripción
Este programa verifica si un número es primo o no.
La implementación se realiza en:
✅ Assembly ARM64 para RaspbianOS en Raspberry Pi
🔧 Compilación en Raspberry Pi (ARM64)
as primo.s -o primo.o
ld primo.o -o primo
▶️ Ejecución
./primo
👀 Código fuente
🔗 Código fuente en Gist: Programa 17 Verificador de números primos 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/08 |
| • Descripción: Programa que verifica si un numero es |
| primo o no en Javascript y Assembly ARM64 para RaspbianOS. |
| • Demostración: |
| https://asciinema.org/a/713369 |
| • Compilación (Raspberry Pi ARM64): |
| as primo.s -o primo.o |
| ld primo.o -o primo |
| • Ejecución: ./primo |
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje Javascript •°•═══════
const testNumber = 97;
const msgTesting = "Verificando si el número ";
const msgIsPrime = " es primo: SÍ\n";
const msgNotPrime = " es primo: NO\n";
const msgReason = "Divisible por: ";
const newline = "\n";
function main() {
process.stdout.write(msgTesting);
process.stdout.write(testNumber.toString());
if (testNumber <= 1) {
process.stdout.write(msgNotPrime);
return;
}
if (testNumber === 2) {
process.stdout.write(msgIsPrime);
return;
}
if ((testNumber & 1) === 0) {
process.stdout.write(msgNotPrime);
process.stdout.write(msgReason + "2" + newline);
return;
}
const limit = Math.floor(Math.sqrt(testNumber)) + 1;
for (let factor = 3; factor <= limit; factor += 2) {
if (testNumber % factor === 0) {
process.stdout.write(msgNotPrime);
process.stdout.write(msgReason + factor.toString() + newline);
return;
}
}
process.stdout.write(msgIsPrime);
}
main();
════════════════════•°• ☆ •°•══════════════════════════════
/*
/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */
.global _start // Punto de entrada global
.data
// Número a verificar
test_number:
.word 97
// Mensajes
msg_testing:
.ascii "Verificando si el número "
msg_testing_len = . - msg_testing
msg_is_prime:
.ascii " es primo: SÍ\n"
msg_is_prime_len = . - msg_is_prime
msg_not_prime:
.ascii " es primo: NO\n"
msg_not_prime_len = . - msg_not_prime
msg_reason:
.ascii "Divisible por: "
msg_reason_len = . - msg_reason
newline:
.ascii "\n"
newline_len = . - newline
// Búfer para convertir números a texto
buffer:
.skip 20
.text
_start:
// Cargar el número a verificar
adr x19, test_number
ldr w19, [x19] // w19 = número a verificar
// Mostrar mensaje inicial
mov x0, #1
adr x1, msg_testing
mov x2, #msg_testing_len
mov x8, #64
svc #0
// Mostrar el número a verificar
mov x24, x19
bl num_to_ascii
// Caso especial: si el número es menor o igual a 1, no es primo
cmp w19, #1
b.le not_prime
// Caso especial: si el número es 2, es primo
cmp w19, #2
b.eq is_prime
// Caso especial: si es par (excepto 2), no es primo
and w24, w19, #1 // Verificar último bit (0 si es par)
cbnz w24, check_prime
// Es par y no es 2, así que no es primo
mov w20, #2 // Factor por el cual es divisible
b not_prime
check_prime:
// Inicializar para la comprobación
mov w20, #3 // Empezar a verificar desde 3
// Calcular la raíz cuadrada aproximada para optimizar
// Usaremos método simplificado: dividir entre 2 y sumar 1
lsr w21, w19, #1 // w21 = número / 2
add w21, w21, #1 // Para redondear hacia arriba
prime_loop:
// Comparar si ya hemos llegado al límite
cmp w20, w21
b.gt is_prime // Si superamos la raíz cuadrada, es primo
// Verificar si es divisible por el factor actual
sdiv w22, w19, w20 // w22 = número / factor
msub w23, w22, w20, w19 // w23 = número - (factor * (número/factor)) = número % factor
// Si el residuo es 0, no es primo
cbz w23, not_prime
// Incrementar factor en 2 (saltando números pares)
add w20, w20, #2
b prime_loop
is_prime:
// Mostrar mensaje que es primo
mov x0, #1
adr x1, msg_is_prime
mov x2, #msg_is_prime_len
mov x8, #64
svc #0
b exit_program
not_prime:
// Mostrar mensaje que no es primo
mov x0, #1
adr x1, msg_not_prime
mov x2, #msg_not_prime_len
mov x8, #64
svc #0
// Mostrar el factor por el que es divisible
mov x0, #1
adr x1, msg_reason
mov x2, #msg_reason_len
mov x8, #64
svc #0
// Mostrar el factor
mov x24, x20
bl num_to_ascii
// Mostrar nueva línea
mov x0, #1
adr x1, newline
mov x2, #newline_len
mov x8, #64
svc #0
exit_program:
// Salir del programa
mov x0, #0
mov x8, #93
svc #0
// 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