GNU/Linux xterm-256color bash 161 views

// ****************************************************************************
// * Lenguajes de Interfaz en TECNM Campus ITT
// * Nombre del archivo: practica.s
// * Descripción: Programa que confirma si el numero es Armstrong
// * Autor: [America Fernanda Nevarez de la Cruz]
// * Fecha: [2025-04-08]
// * Plataforma: Raspberry Pi OS (64 bits)
// * Demostración:  [https://asciinema.org/a/JqwTLho4orjXTe0nDmr58dNxs]
// ****************************************************************************

// ****************************************************************************
// * Codigo equivalente en Ruby
// *def atoi(str)
// *  num = 0
// *  str.each_char do |c|
// *    if c >= '0' && c <= '9'
// *      num = num * 10 + (c.ord - '0'.ord)
// *    else
// *      break
// *    end
// *  end
// *  num
// *end
// ****************************************************************************

.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 leer la entrada

.section .text
.global _start

_start:
    // Mostrar mensaje de entrada
    ldr x0, =msg_input
    mov x1, #len_input
    bl print_msg

    // Leer entrada de usuario
    mov x0, #0          // stdin
    ldr x1, =buffer
    mov x2, #16
    mov x8, #63         // syscall read
    svc #0

    // Convertir cadena a número
    ldr x1, =buffer
    bl atoi
    mov x19, x0         // Guardamos número en x19

    // Verificar número de Armstrong
    mov x1, x19         // copia para trabajar
    mov x2, #0          // suma de cubos
    mov x3, #10

loop_digits:
    udiv x4, x1, x3     // x4 = x1 / 10
    msub x5, x4, x3, x1 // x5 = x1 - x4*10 (dígito)
    mov x6, x5
    mul x6, x6, x5
    mul x6, x6, x5
    add x2, x2, x6
    mov x1, x4
    cbz x1, end_loop
    b loop_digits

end_loop:
    cmp x2, x19
    b.eq print_yes

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:
    mov x8, #93
    mov x0, #0
    svc #0

// ------------ Funciones auxiliares ------------

// print_msg(x0 = ptr, x1 = len)
print_msg:
    mov x2, x1
    mov x1, x0
    mov x0, #1      // stdout
    mov x8, #64     // write syscall
    svc #0
    ret

// atoi(x1 = ptr a buffer) -> x0 = número
atoi:
    mov x0, #0
    mov x3, #10
atoi_loop:
    ldrb w2, [x1], #1
    cmp w2, #'0'
    blt atoi_done
    cmp w2, #'9'
    bgt atoi_done
    sub w2, w2, #'0'
    mul x0, x0, x3    // multiplicar x0 por 10
    add x0, x0, x2
    b atoi_loop

atoi_done:
    ret