GNU/Linux xterm-256color bash 193 views

// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Suma los digitos que integran una  cadena de numeros
// * Autor: Roldan Castro Luis Alberto
// * Fecha: 08-04-2025
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/fTpnzqJSU69U73ZwanojQ4D9N
// ****************************************************************************

// ****************************************************************************
//  Codigo en JAVA
// *public class SumaDigitos {
// *    public static void main(String[] args) {
// *        Scanner scanner = new Scanner(System.in);
// *        int suma = 0;
// *
// *        // * Mostrar mensaje
// *        System.out.print("Ingrese un numero: ");
// *
// *        // * Leer entrada del usuario
// *        String input = scanner.nextLine();
// *
// *        // * Sumar cada dígito
// *        for (int i = 0; i < input.length(); i++) {
// *            char c = input.charAt(i);
// *            
// *            // * Verificar si es dígito
// *            if (Character.isDigit(c)) {
// *                // * Convertir carácter a valor numérico y sumar
// *                suma += Character.getNumericValue(c);
// *            }
// *        }
// *
// *        // * Mostrar resultado
// *        System.out.println("Suma de los digitos: " + suma);
// *
// *        scanner.close();
// *    }
// *}
// ****************************************************************************

.section .bss
buffer: .skip 64                // Reservar espacio para almacenar la entrada del usuario

.section .data
msg_ingrese: .ascii "Ingrese un numero entero: "  // Mensaje de solicitud para ingresar un número
len_ingrese = . - msg_ingrese

msg_resultado: .ascii "Suma de los digitos: "     // Mensaje que muestra la suma de los dígitos
len_resultado = . - msg_resultado

newline: .ascii "\n"             // Salto de línea para la salida
len_nl = . - newline             // Longitud del salto de línea

.section .text
.global _start

_start:
    // Mostrar mensaje de solicitud de entrada
    ldr x0, =msg_ingrese
    mov x1, #len_ingrese
    bl print_msg

    // Leer la entrada del usuario desde stdin
    mov x0, #0                 // stdin (entrada estándar)
    ldr x1, =buffer            // Dirección del buffer donde se almacenará la entrada
    mov x2, #64                // Tamaño máximo del buffer
    mov x8, #63                // syscall read (lectura desde stdin)
    svc #0                     // Invocar syscall para leer la entrada
    mov x9, x0                 // x9 = longitud de los datos leídos
    ldr x1, =buffer            // x1 apunta al buffer donde se almacenó la entrada

    // Inicializar variable para la suma de los dígitos
    mov x3, #0                 // x3 = suma (inicia en 0)

sumar_loop:
    cbz x9, mostrar            // Si no hay más caracteres por leer, muestra el resultado

    ldrb w2, [x1], #1          // Cargar el siguiente carácter de la entrada
    sub x9, x9, #1             // Reducir el contador de caracteres restantes

    cmp w2, #'0'               // Si el carácter es menor que '0', ignorarlo
    blt sumar_loop             // Si no es un dígito, continuar al siguiente carácter

    cmp w2, #'9'               // Si el carácter es mayor que '9', ignorarlo
    bgt sumar_loop             // Si no es un dígito, continuar al siguiente carácter

    sub w2, w2, #'0'           // Convertir el carácter ASCII en un número (restar '0')
    add w3, w3, w2             // Sumar el valor del dígito a la suma acumulada

    b sumar_loop               // Continuar procesando el siguiente carácter

mostrar:
    // Mostrar el mensaje "Suma de los dígitos"
    ldr x0, =msg_resultado
    mov x1, #len_resultado
    bl print_msg

    // Imprimir la suma total de los dígitos
    mov x0, x3                 // x0 = suma total
    bl print_number

    // Imprimir salto de línea
    ldr x0, =newline
    mov x1, #len_nl
    bl print_msg

    // Salir del programa
    mov x8, #93                // syscall exit (salir del programa)
    mov x0, #0                 // Código de salida
    svc #0                     // Invocar syscall para salir

// Función para imprimir un mensaje
print_msg:
    mov x2, x1                 // Longitud del mensaje
    mov x1, x0                 // Dirección del mensaje
    mov x0, #1                 // Especifica salida estándar (stdout)
    mov x8, #64                // syscall write (escribir)
    svc #0                     // Invocar syscall para imprimir el mensaje
    ret

// Función para imprimir números
print_number:
    mov x1, x0                 // Copiar el número a imprimir en x1
    ldr x2, =buffer            // Dirección del buffer donde se almacenará el número
    add x2, x2, #63            // Apuntar al final del buffer
    mov w3, #0                 // Contador de dígitos

convert_loop:
    mov x4, #10                // Base 10 para la división
    udiv x5, x1, x4            // x5 = x1 / 10
    msub x6, x5, x4, x1        // x6 = x1 - x5 * 10 (residuo)
    add x6, x6, #'0'           // Convertir el residuo a carácter ASCII
    strb w6, [x2], #-1          // Almacenar el carácter en el buffer
    mov x1, x5                 // Actualizar x1 para la siguiente división
    add w3, w3, #1             // Incrementar contador de dígitos
    cbnz x1, convert_loop      // Continuar si quedan más dígitos

    add x2, x2, #1             // Ajustar el puntero al inicio del buffer
    mov x1, x2                 // Dirección del buffer
    mov w2, w3                 // Número de dígitos en w3
    mov x0, #1                 // Especificar salida estándar (stdout)
    mov x8, #64                // syscall write (escribir)
    svc #0                     // Invocar syscall para imprimir el número
    ret