GNU/Linux xterm bash 100 views

📌 Demostración: Factorial de un número(1 al 20) en ARM64 Assembly

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

🎯 Descripción

Este programa calcula el factorial de un número a escoger del 1 al 20 y muestra el resultado en la terminal.
La implementación se realiza en:

Assembly ARM64 para RaspbianOS en Raspberry Pi

🔧 Compilación en Raspberry Pi (ARM64)

as factorial.s -o factorial.o  
ld factorial.o -o factorial

▶️ Ejecución

./factorial

👀 Código fuente

🔗 Código fuente en Gist: Programa 34 Factorial de un número(1 al 20), muestra resultado en la terminal 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/10                                                         | 
| • Descripción: Programa que calcula el factorial de un numero y muestra     | 
|   el resutado en terminal en C# y Assembly ARM64 para RaspbianOS.           | 
| • Demostración:                                                             |
|   https://asciinema.org/a/714554                                            |
| • Compilación (Raspberry Pi ARM64):                                         |  
|     as fectorial.s -o factorial.o                                           |  
|     ld factorial.o -o factorial                                             |  
| • Ejecución: ./factorial                                                    |  
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄                                       

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

using System;

class FactorialRaw
{
    static void Main()
    {
        Console.Write("Introduce un número: ");
        int number = int.Parse(Console.ReadLine());
        
        long factorial = 1;
        for (int i = 1; i <= number; i++)
        {
            factorial *= i;
        }
        
        Console.WriteLine($"El factorial es: {factorial}");
    }
}

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

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

.section .data
prompt:     .ascii  "Introduce un número (0-20): "
prompt_len = . - prompt
result_msg: .ascii  "El factorial es: "
result_len = . - result_msg
newline:    .ascii  "\n"
newline_len = . - newline
error_msg:  .ascii  "Error: Número inválido\n"
error_len = . - error_msg

.section .bss
.lcomm input, 21    // Buffer para entrada (máx 20 dígitos)
.lcomm output, 21   // Buffer para salida

.section .text
.global _start
.align 4

_start:
    // Mostrar prompt
    mov x0, #1          // stdout
    adr x1, prompt      // mensaje
    mov x2, prompt_len  // longitud
    mov x8, #64         // syscall write
    svc #0

    // Leer entrada
    mov x0, #0          // stdin
    adr x1, input       // buffer
    mov x2, #21         // longitud máxima
    mov x8, #63         // syscall read
    svc #0

    // Convertir ASCII a número (x19 = número)
    adr x1, input
    mov x19, #0         // acumulador
    mov x20, #10        // base 10

convert_loop:
    ldrb w2, [x1], #1   // cargar byte y avanzar
    cmp w2, #'\n'       // fin de línea?
    b.eq convert_done
    sub w2, w2, #'0'    // convertir ASCII a dígito
    cmp w2, #0          // verificar rango 0-9
    b.lt invalid_input
    cmp w2, #9
    b.gt invalid_input
    madd x19, x19, x20, x2  // num = num * 10 + dígito
    b convert_loop

convert_done:
    // Verificar que el número sea <= 20 (factorial de 21 desborda 64 bits)
    cmp x19, #20
    b.gt invalid_input

    // Calcular factorial (x0 = factorial(x19))
    mov x0, #1          // resultado inicial
    mov x1, #1          // contador

factorial_loop:
    cmp x1, x19
    b.gt factorial_done
    mul x0, x0, x1      // resultado *= contador
    add x1, x1, #1      // contador++
    b factorial_loop

factorial_done:
    // Convertir resultado a ASCII (x0 contiene el resultado)
    adr x1, output + 20 // apuntar al final del buffer
    mov w2, #0          // terminador nulo

convert_to_ascii:
    mov x3, #10
    udiv x4, x0, x3     // x4 = x0 / 10
    msub x5, x4, x3, x0 // x5 = x0 % 10
    add w5, w5, #'0'    // convertir a ASCII
    strb w5, [x1], #-1  // almacenar y retroceder
    mov x0, x4          // x0 = cociente
    cbnz x0, convert_to_ascii

    // Ajustar puntero al inicio del número
    add x1, x1, #1

    // Mostrar "El factorial es: "
    mov x0, #1
    adr x2, result_msg
    mov x3, result_len
    mov x8, #64
    svc #0

    // Mostrar el número
    mov x0, #1
    // x1 ya apunta al número
    adr x2, output + 20
    sub x2, x2, x1      // calcular longitud
    mov x8, #64
    svc #0

    // Mostrar nueva línea
    mov x0, #1
    adr x1, newline
    mov x2, newline_len
    mov x8, #64
    svc #0

    // Salir
    b exit

invalid_input:
    // Mostrar mensaje de error
    mov x0, #1
    adr x1, error_msg
    mov x2, error_len
    mov x8, #64
    svc #0

exit:
    // Terminar programa
    mov x0, #0          // código de salida 0
    mov x8, #93         // syscall exit
    svc #0