// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Determinar si un numero es narcicista
// * Autor: Roldan Castro Luis Alberto
// * Fecha: 08-04-2025
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/iyXl3cAxT7AtITL2Rrt8mfdnS
// ****************************************************************************
// ****************************************************************************
// Version en JAVA
//
//import java.util.Scanner;
//
//public class ArmstrongNumber {
// public static void main(String[] args) {
// Scanner scanner = new Scanner(System.in);
//
// // Solicitar entrada del usuario
// System.out.print("Ingresa un numero: ");
// int num = scanner.nextInt();
// scanner.close();
//
// // Verificar si el número es de Armstrong
// if (isArmstrong(num)) {
// System.out.println("Es un numero de Armstrong");
// } else {
// System.out.println("No es un numero de Armstrong");
// }
// }
//
// public static boolean isArmstrong(int number) {
// int original = number;
// int sum = 0;
//
// while (number > 0) {
// int digit = number % 10;
// sum += Math.pow(digit, 3);
// number /= 10;
// }
//
// return sum == original;
// }
//}
// ****************************************************************************
.section .data
msg_input: .ascii "Ingresa un numero: "
len_input = . - msg_input
msg_yes: .ascii "Es un numero de Armstrong\n"
len_yes = . - msg_yes
msg_no: .ascii "No es un numero de Armstrong\n"
len_no = . - msg_no
.section .bss
buffer: .skip 16 // Espacio para guardar la entrada del usuario (hasta 15 caracteres + '\n')
.section .text
.global _start
_start:
// --- Mostrar mensaje de entrada ---
ldr x0, =msg_input // Dirección del mensaje
mov x1, #len_input // Longitud del mensaje
bl print_msg // Llama a la función para imprimir
// --- Leer entrada del usuario ---
mov x0, #0 // stdin
ldr x1, =buffer // Dirección donde guardar entrada
mov x2, #16 // Tamaño máximo a leer
mov x8, #63 // syscall read
svc #0
// --- Convertir cadena a número ---
ldr x1, =buffer // Dirección del buffer con texto
bl atoi // Convierte a número (resultado en x0)
mov x19, x0 // Guardamos el número original en x19
// --- Verificar si es número de Armstrong ---
mov x1, x19 // Copiamos el número a x1 para trabajarlo
mov x2, #0 // Acumulador para la suma de cubos
mov x3, #10 // Constante 10 para extraer dígitos
loop_digits:
udiv x4, x1, x3 // x4 = x1 / 10 (número sin el último dígito)
msub x5, x4, x3, x1 // x5 = x1 - x4 * 10 → último dígito (módulo)
// Calcular el cubo del dígito: x5^3
mov x6, x5
mul x6, x6, x5
mul x6, x6, x5
// Sumar a la suma total de cubos
add x2, x2, x6
mov x1, x4 // Reducimos el número (quitamos el último dígito)
cbz x1, end_loop // Si x1 == 0, terminamos el ciclo
b loop_digits
end_loop:
// Comparamos suma de cubos con número original
cmp x2, x19
b.eq print_yes // Si son iguales, es un número de Armstrong
print_no:
ldr x0, =msg_no
mov x1, #len_no
bl print_msg
b end_prog
print_yes:
ldr x0, =msg_yes
mov x1, #len_yes
bl print_msg
end_prog:
// Salida del programa (sys_exit)
mov x8, #93
mov x0, #0
svc #0
// --------- Funciones auxiliares ---------
// print_msg(x0 = dirección del mensaje, x1 = longitud)
print_msg:
mov x2, x1 // Longitud
mov x1, x0 // Dirección del mensaje
mov x0, #1 // stdout
mov x8, #64 // syscall write
svc #0
ret
// atoi(x1 = dirección del buffer) → x0 = número entero
atoi:
mov x0, #0 // Resultado acumulado
mov x3, #10 // Base decimal
atoi_loop:
ldrb w2, [x1], #1 // Cargar siguiente byte del buffer y avanzar el puntero
cmp w2, #'0' // ¿Es menor que '0'?
blt atoi_done // Sí: fin
cmp w2, #'9' // ¿Es mayor que '9'?
bgt atoi_done // Sí: fin
sub w2, w2, #'0' // Convertir carácter a dígito (ASCII → número)
mul x0, x0, x3 // Multiplicar acumulador por 10
add x0, x0, x2 // Sumar el nuevo dígito
b atoi_loop
atoi_done:
ret