GNU/Linux xterm bash 93 views

📌 Demostración: Generador de secuencia Fibonacci(Primeros 10 números) en ARM64 Assembly

💻 Lenguajes de Interfaz en TECNM Campus ITT
👨‍💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/08

🎯 Descripción

Este programa genera los primeros 10 números de la secuencia Fibonacci.
La implementación se realiza en:

Assembly ARM64 para RaspbianOS en Raspberry Pi

🔧 Compilación en Raspberry Pi (ARM64)

as fibonacci.s -o fibonacci.o  
ld fibonacci.o -o fibonacci 

▶️ Ejecución

./fibonacci

👀 Código fuente

🔗 Código fuente en Gist: Programa 15 Generador de secuencia Fibonacci(Primeros 10 numeros) 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 muestra los primeros 10 numeros de la      | 
|   secuencia de Fibonacci en  Rust y Assembly ARM64 para RaspbianOS.    | 
| • Demostración:                                                        |
|   https://asciinema.org/a/713358                                       |
| • Compilación (Raspberry Pi ARM64):                                    |  
|     as fibonacci.s -o fibonacci.o                                      |  
|     ld fibonacci.o -o fibonacci                                        |  
| • Ejecución: ./fibonacci                                               |  
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄                                        

⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje Rust •°•═══════

use std::io::{self, Write};

fn main() {
    println!("Secuencia de Fibonacci (primeros 10 números):");
    
    let mut fib_n_2 = 0;
    let mut fib_n_1 = 1;
    let mut count = 0;
    let total = 10;
    
    print_number(fib_n_2);
    count += 1;
    
    if count >= total {
        return;
    }
    
    print_separator();
    print_number(fib_n_1);
    count += 1;
    
    while count < total {
        let fib_n = fib_n_1 + fib_n_2;
        fib_n_2 = fib_n_1;
        fib_n_1 = fib_n;
        print_separator();
        print_number(fib_n);
        count += 1;
    }
    
    println!();
}

fn print_number(num: u32) {
    print!("{}", num);
    io::stdout().flush().unwrap();
}

fn print_separator() {
    print!(", ");
    io::stdout().flush().unwrap();
}

════════════════════•°• ☆ •°•══════════════════════════════
/*

/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */

.global _start      // Punto de entrada global

.data
// Mensaje de inicio
intro_msg:
    .ascii "Secuencia de Fibonacci (primeros 10 números):\n"
intro_len = . - intro_msg

// Mensaje para separar números
separator:
    .ascii ", "
separator_len = . - separator

newline:
    .ascii "\n"
newline_len = . - newline

// Búfer para convertir números a texto
buffer:
    .skip 20

.text
_start:
    // Imprimir mensaje de introducción
    mov x0, #1                 // File descriptor: 1 para stdout
    adr x1, intro_msg          // Dirección del mensaje
    mov x2, #intro_len         // Longitud del mensaje
    mov x8, #64                // Syscall número 64: write
    svc #0                     // Llamada al sistema

    // Inicializar variables para Fibonacci
    mov x19, #0                // Primer número (F_n-2)
    mov x20, #1                // Segundo número (F_n-1)
    mov x21, #0                // Contador de números generados
    mov x22, #10               // Total de números a generar

    // Imprimir el primer número (0)
    bl print_number
    
    // Incrementar contador
    add x21, x21, #1
    
    // Comprobar si hemos terminado
    cmp x21, x22
    b.ge exit_program
    
    // Imprimir separador
    bl print_separator
    
    // Imprimir el segundo número (1)
    mov x19, x20               // Temporalmente mover el segundo número a x19 para imprimirlo
    bl print_number
    mov x19, #0                // Restaurar x19 a su valor original
    
    // Incrementar contador
    add x21, x21, #1

fibonacci_loop:
    // Comprobar si hemos terminado
    cmp x21, x22
    b.ge exit_program
    
    // Calcular siguiente número Fibonacci: F_n = F_n-1 + F_n-2
    add x23, x19, x20          // x23 = F_n = F_n-1 + F_n-2
    
    // Imprimir separador
    bl print_separator
    
    // Imprimir número
    mov x19, x23               // Mover el resultado a x19 para imprimirlo
    bl print_number
    
    // Actualizar valores para la próxima iteración (CORREGIDO)
    mov x24, x20               // Guardar F_n-1 temporalmente
    mov x20, x23               // F_n-1 = F_n
    mov x19, x24               // F_n-2 = anterior F_n-1
    
    // Incrementar contador
    add x21, x21, #1
    
    b fibonacci_loop

// Subrutina para imprimir un número
print_number:
    // Preparar para convertir el número a texto
    mov x24, x19               // Copiar número a x24
    adr x25, buffer            // x25 = puntero al búfer
    add x25, x25, #19          // Empezar desde el final del búfer
    mov x26, #10               // x26 = base 10 para división
    
    // Caso especial si el número es 0
    cbnz x24, convert_loop
    mov w27, '0'               // Carácter ASCII '0'
    strb w27, [x25]
    sub x25, x25, #1
    b end_convert

convert_loop:
    // Comprobar si el número es 0
    cbz x24, end_convert
    
    // Obtener el último dígito (número % 10)
    udiv x27, x24, x26         // x27 = x24 / 10
    msub x28, x27, x26, x24    // x28 = x24 - (x27 * 10) = x24 % 10
    
    // Convertir dígito a ASCII y guardarlo
    add w28, w28, #'0'         // Convertir a carácter ASCII
    strb w28, [x25]            // Guardar en búfer
    sub x25, x25, #1           // Mover puntero
    
    // Actualizar número para siguiente iteración
    mov x24, x27               // Número = número / 10
    b convert_loop

end_convert:
    // Calcular longitud de la cadena resultante
    add x25, x25, #1           // Ajustar puntero al primer dígito
    adr x24, buffer
    add x24, x24, #20
    sub x2, x24, x25           // x2 = longitud de la cadena
    
    // Imprimir número
    mov x0, #1                 // File descriptor: 1 para stdout
    mov x1, x25                // Dirección del búfer
    mov x8, #64                // Syscall número 64: write
    svc #0                     // Llamada al sistema
    
    ret

// Subrutina para imprimir separador
print_separator:
    mov x0, #1                 // File descriptor: 1 para stdout
    adr x1, separator          // Dirección del separador
    mov x2, #separator_len     // Longitud del separador
    mov x8, #64                // Syscall número 64: write
    svc #0                     // Llamada al sistema
    ret

exit_program:
    // Imprimir nueva línea al final
    mov x0, #1                 // File descriptor: 1 para stdout
    adr x1, newline            // Dirección del mensaje
    mov x2, #newline_len       // Longitud del mensaje
    mov x8, #64                // Syscall número 64: write
    svc #0                     // Llamada al sistema

    // Salir del programa
    mov x0, #0                 // Código de salida: 0 (éxito)
    mov x8, #93                // Syscall número 93: exit
    svc #0                     // Llamada al sistema