// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Calcular la suma de los números primos que se encuentran en las posiciones de la secuencia de Fibonacci
// * Autor: Roldan Castro Luis Alberto
// * Fecha: 08-04-2025
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/nEqGXpPsbIHAhcztKUPyk3tLH
// ****************************************************************************
// ****************************************************************************
// Version en python
//
//# Función para verificar si un número es primo
//def is_prime(num):
// if num < 2:
// return False
// for i in range(2, int(num ** 0.5) + 1):
// if num % i == 0:
// return False
// return True
//
//# Función para generar la secuencia de Fibonacci hasta N
//def generate_fibonacci(N):
// fibs = [0, 1]
// for i in range(2, N):
// fibs.append(fibs[i - 1] + fibs[i - 2])
// return fibs
//
//# Función para convertir un número a una cadena (para mostrar)
//def number_to_string(num):
// return str(num)
//
//# Función principal
//def main():
// # Solicitar al usuario el número N
// N = int(input("Ingresa un número: "))
//
// # Generar la secuencia de Fibonacci hasta N
// fibonacci = generate_fibonacci(N)
//
// # Sumar los términos en posiciones primas
// total_sum = 0
// for i in range(2, N): # Comienza desde 2 porque los primeros números (0, 1) no son primos
// if is_prime(i):
// total_sum += fibonacci[i]
//
// # Mostrar el resultado
// print(f"Suma de Fibonacci en posiciones primas: {number_to_string(total_sum)}")
//
//if __name__ == "__main__":
// main()
// ****************************************************************************
.section .data
msg_input: .ascii "Ingresa las posiciones: "
len_input = . - msg_input
msg_result: .ascii "Suma de Fibonacci en posiciones primas: \n"
len_result = . - msg_result
newline: .ascii "\n" // Salto de línea
len_newline = . - newline
.section .bss
buffer: .skip 16 // espacio para entrada del usuario
fibs: .skip 8 * 64 // espacio para hasta 64 términos
result: .skip 8 // acumulador de la suma
.section .text
.global _start
_start:
// Mostrar mensaje de entrada
ldr x0, =msg_input
mov x1, #len_input
bl print_msg
// Leer número desde consola
mov x0, #0 // stdin
ldr x1, =buffer
mov x2, #16
mov x8, #63 // syscall read
svc #0
// Convertir a número
ldr x1, =buffer
bl atoi // devuelve número en x0
mov x21, x0 // guardar N en x21
// Generar Fibonacci hasta N
mov x0, #0
ldr x1, =fibs
str x0, [x1], #8 // fib[0] = 0
mov x0, #1
str x0, [x1], #8 // fib[1] = 1
mov x2, #2
gen_fib_loop:
cmp x2, x21
bge done_fib
sub x4, x2, #1
sub x5, x2, #2
ldr x6, =fibs
ldr x7, [x6, x4, LSL #3]
ldr x8, [x6, x5, LSL #3]
add x9, x7, x8
str x9, [x6, x2, LSL #3]
add x2, x2, #1
b gen_fib_loop
done_fib:
// Sumar solo los términos en posiciones primas
mov x19, #0 // acumulador
mov x20, #1 // posición
sum_loop:
cmp x20, x21
bgt end_prog
mov x0, x20
bl is_prime
cbz x0, not_prime
// Sumar fib[x20] a x19
ldr x1, =fibs
ldr x2, [x1, x20, LSL #3]
add x19, x19, x2
not_prime:
add x20, x20, #1
b sum_loop
end_prog:
// Mostrar mensaje
ldr x0, =msg_result
mov x1, #len_result
bl print_msg
// Convertir x19 a ASCII y mostrar
mov x0, x19
bl print_number
// Imprimir salto de línea
ldr x0, =newline // Cargar el salto de línea
mov x1, #len_newline // Longitud del salto de línea
bl print_msg // Imprimir salto de línea
// Salir
mov x8, #93
mov x0, #0
svc #0
// ------------ Funciones auxiliares ------------
// print_msg(x0 = ptr, x1 = len)
print_msg:
mov x2, x1
mov x1, x0
mov x0, #1 // stdout
mov x8, #64 // syscall write
svc #0
ret
// atoi(x1 = ptr a buffer) -> x0 = número
atoi:
mov x0, #0
mov x3, #10
atoi_loop:
ldrb w2, [x1], #1
cmp w2, #'0'
blt atoi_done
cmp w2, #'9'
bgt atoi_done
sub w2, w2, #'0'
mul x0, x0, x3
add x0, x0, x2
b atoi_loop
atoi_done:
ret
// is_prime(x0) -> x0 = 1 si es primo, 0 si no
is_prime:
cmp x0, #2
blt not_prime_ret
mov x1, #2
prime_check_loop:
mul x2, x1, x1
cmp x2, x0
bgt prime_yes
udiv x3, x0, x1
msub x4, x3, x1, x0
cbz x4, not_prime_ret
add x1, x1, #1
b prime_check_loop
prime_yes:
mov x0, #1
ret
not_prime_ret:
mov x0, #0
ret
// print_number(x0 = número a imprimir)
print_number:
mov x1, x0 // número original
mov x2, #10 // divisor
ldr x3, =buffer
add x3, x3, #15 // apuntar al final
mov x4, #0
print_num_loop:
udiv x5, x1, x2
msub x6, x5, x2, x1
add x6, x6, #'0'
strb w6, [x3], #-1
mov x1, x5
add x4, x4, #1
cbz x1, print_num_done
b print_num_loop
print_num_done:
add x3, x3, #1
mov x0, #1 // stdout
mov x1, x3
mov x2, x4
mov x8, #64 // syscall write
svc #0
ret