// ****************************************************************************
// * 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