// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Sumar los numeros anteriores a N
// * Autor: Roldan Castro Luis Alberto
// * Fecha: 07-04-2025
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/ynGRHarvCAYpPRIiwEdwptyPI
// ****************************************************************************
// ****************************************************************************
// Version en python
//
//def suma_anteriores(n):
// return sum(range(n))
//
//# Ejemplo de uso
//N = int(input("Ingrese un número: "))
//print(f"La suma de los números anteriores a {N} es: {suma_anteriores(N)}")
//
// ****************************************************************************
.section .bss
buffer: .skip 64 // Reservar 64 bytes de memoria para almacenar la entrada del usuario
.section .data
msg_ingrese: .ascii "Ingrese un numero: " // Mensaje para pedir al usuario un número
len_ingrese = . - msg_ingrese // Longitud del mensaje "Ingrese un numero: "
msg_resultado: .ascii "Resultado: " // Mensaje para mostrar el resultado
len_resultado = . - msg_resultado // Longitud del mensaje "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 para pedir el número
ldr x0, =msg_ingrese // Cargar la dirección del mensaje "Ingrese un numero: "
mov x1, #len_ingrese // Cargar la longitud del mensaje
bl print_msg // Llamar a la función para imprimir el mensaje
// Leer el número ingresado por el usuario
mov x0, #0 // Descriptor de archivo para entrada estándar (0 = stdin)
ldr x1, =buffer // Dirección del buffer donde se almacenará la entrada
mov x2, #64 // Tamaño del buffer
mov x8, #63 // Llamada al sistema para leer desde la entrada (sys_read)
svc #0 // Realizar la llamada al sistema
// Convertir texto ingresado a número
ldr x1, =buffer // Dirección del buffer que contiene el texto
mov x2, #0 // Inicializar el acumulador a 0 (para el número)
parse_loop:
ldrb w3, [x1], #1 // Cargar un byte del buffer
cmp w3, #'0' // Comparar con el carácter '0'
blt fin_parse // Si es menor que '0', terminamos
cmp w3, #'9' // Comparar con el carácter '9'
bgt fin_parse // Si es mayor que '9', terminamos
sub w3, w3, #'0' // Convertir el carácter a su valor numérico
mov w4, #10 // Número por el cual multiplicamos el acumulador
mul w2, w2, w4 // Multiplicar el acumulador por 10
add w2, w2, w3 // Sumar el valor del dígito
b parse_loop // Continuar con el siguiente carácter
fin_parse:
mov x10, x2 // Guardar el número final en x10
// Calcular la sumatoria del 1 al N
mov x3, #1 // Inicializar i = 1
mov x4, #0 // Inicializar suma = 0
sum_loop:
cmp x3, x10 // Comparar i con el número N
bgt mostrar // Si i > N, mostrar el resultado
add x4, x4, x3 // suma += i
add x3, x3, #1 // Incrementar i
b sum_loop // Continuar con la sumatoria
mostrar:
// Mostrar el mensaje "Resultado:"
ldr x0, =msg_resultado // Cargar la dirección del mensaje "Resultado: "
mov x1, #len_resultado // Cargar la longitud del mensaje
bl print_msg // Llamar a la función para imprimir el mensaje
// Mostrar la suma calculada
mov x0, x4 // Cargar la suma en x0
bl print_number // Llamar a la función para imprimir el número
// Imprimir un salto de línea
ldr x0, =newline // Cargar la dirección del salto de línea
mov x1, #len_nl // Cargar la longitud del salto de línea
bl print_msg // Llamar a la función para imprimir el salto de línea
// Salir del programa
mov x8, #93 // Llamada al sistema para salir del programa
mov x0, #0 // Código de salida (0 = éxito)
svc #0 // Realizar la llamada al sistema
// --- Función: imprimir mensaje ---
print_msg:
mov x2, x1 // Longitud del mensaje
mov x1, x0 // Dirección del mensaje
mov x0, #1 // Descriptor de archivo para salida estándar (1 = stdout)
mov x8, #64 // Llamada al sistema para escribir (sys_write)
svc #0 // Realizar la llamada al sistema
ret
// --- Función: imprimir número ---
print_number:
mov x1, x0 // Número a imprimir
ldr x2, =buffer // Dirección donde se almacenará el número como texto
add x2, x2, #63 // Ajustar el puntero para escribir desde el final del buffer
mov w3, #0 // Contador de dígitos
convert_loop:
mov x4, #10 // Factor para dividir el número
udiv x5, x1, x4 // Dividir x1 entre 10
msub x6, x5, x4, x1 // Resto de la división (x1 % 10)
add x6, x6, #'0' // Convertir el resto a un carácter ASCII
strb w6, [x2], #-1 // Almacenar el carácter en el buffer
mov x1, x5 // Actualizar x1 para la siguiente iteración
add w3, w3, #1 // Incrementar el contador de dígitos
cbnz x1, convert_loop // Continuar si hay más dígitos
add x2, x2, #1 // Ajustar el puntero del buffer
mov x1, x2 // Dirección final del número
mov w2, w3 // Número de dígitos
mov x0, #1 // Descriptor de salida (1 = stdout)
mov x8, #64 // Llamada al sistema para escribir
svc #0 // Realizar la llamada al sistema
ret