GNU/Linux xterm-256color bash 131 views

// Autor: Victor
// Fecha: 02/04/2025 
// Descripción: Suma dos números enteros ingresados por el usuario en Raspbian OS
// Demostración: [https://asciinema.org/a/aGNUECvq2hEAGGd8Ik3mWgOFd]


  /*
    Código equivalente en C#:
    using System;

    class Program {
        static void Main() {
            Console.Write("Ingrese el primer número: ");
            int a = int.Parse(Console.ReadLine());

            Console.Write("Ingrese el segundo número: ");
            int b = int.Parse(Console.ReadLine());

            int suma = a + b;
            Console.WriteLine("La suma es: " + suma);
        }
    }
    */
.section .data
msg1:   .asciz "Ingrese el primer número: "
msg2:   .asciz "Ingrese el segundo número: "
msg3:   .asciz "La suma es: "
newline: .asciz "\n"
buffer: .skip 10  // Espacio para almacenar entrada del usuario

.section .text
.global _start

_start:
    // Mostrar mensaje 1
    mov x0, 1          // STDOUT
    ldr x1, =msg1      // Dirección del mensaje
    mov x2, 27         // Longitud del mensaje
    mov x8, 64         // syscall write
    svc 0              // Llamada al sistema

    // Leer primer número
    mov x0, 0          // STDIN
    ldr x1, =buffer    // Dirección del buffer
    mov x2, 10         // Longitud máxima de entrada
    mov x8, 63         // syscall read
    svc 0              // Llamada al sistema
    
    // Convertir a entero
    ldr x0, =buffer
    bl atoi            // Llama a la función atoi
    mov x20, x0        // Guarda el primer número en x20

    // Mostrar mensaje 2
    mov x0, 1
    ldr x1, =msg2
    mov x2, 27         // Longitud del mensaje
    mov x8, 64
    svc 0

    // Leer segundo número
    mov x0, 0
    ldr x1, =buffer
    mov x2, 10
    mov x8, 63
    svc 0

    // Convertir a entero
    ldr x0, =buffer
    bl atoi
    mov x21, x0        // Guarda el segundo número en x21

    // Sumar los números
    add x22, x20, x21

    // Mostrar resultado
    mov x0, 1
    ldr x1, =msg3
    mov x2, 12         // Longitud del mensaje
    mov x8, 64
    svc 0

    // Imprimir resultado como número
    mov x0, x22
    bl print_int

    // Imprimir salto de línea
    mov x0, 1
    ldr x1, =newline
    mov x2, 1          // Longitud de "\n"
    mov x8, 64
    svc 0

    // Salir
    mov x8, 93
    mov x0, 0
    svc 0

// Función atoi: Convierte string en número
atoi:
    mov x1, #0         // Inicializa resultado en 0
atoi_loop:
    ldrb w2, [x0], #1  // Carga un byte y avanza al siguiente
    cmp w2, #48        // Compara con '0' (ASCII)
    blt atoi_done      // Si es menor, termina
    cmp w2, #57        // Compara con '9' (ASCII)
    bgt atoi_done      // Si es mayor, termina
    sub w2, w2, #48    // Convierte ASCII a número (0-9)
    mov x3, #10        // Carga el valor 10 en un registro
    mul x1, x1, x3     // Multiplica el resultado por 10
    add x1, x1, x2     // Suma el nuevo dígito
    b atoi_loop
atoi_done:
    mov x0, x1
    ret

// Función print_int: Imprime un número en pantalla
print_int:
    sub sp, sp, #16    // Reserva espacio en la pila
    mov x1, sp         // Usa la pila como buffer temporal
    mov x2, #10        // Contador de caracteres
print_int_loop:
    mov x3, #10        // Carga el valor 10 en un registro
    udiv x4, x0, x3    // Divide por 10
    msub x5, x4, x3, x0 // Resto: x5 = x0 - (x4 * x3)
    add x5, x5, #48    // Convierte a ASCII
    sub x2, x2, #1
    strb w5, [x1, x2]  // Guarda el carácter en el buffer
    mov x0, x4         // Actualiza x0 con el cociente
    cbnz x0, print_int_loop // Si no es cero, repite

    // Imprimir número
    mov x0, 1          // STDOUT
    add x1, x1, x2     // Apunta al primer carácter válido
    mov x8, 64         // syscall write
    svc 0
    add sp, sp, #16    // Limpia la pila
    ret