// Programa: Invertir un número en ARM64 Assembly
// Autor: Victor Manuel Madrid Lugo
// Fecha: 03/04/2025
// Descripción: Este programa captura un número entero ingresado por el usuario,
// lo invierte y lo muestra en pantalla.
// Demostración: [ https://asciinema.org/a/thjmidqNkgmtu3f1V4KmWyCcV ]
// Código equivalente en C++:
/*
#include <iostream>
#include <string>
using namespace std;
int main() {
string num;
cout << "Ingresa un número: ";
cin >> num;
reverse(num.begin(), num.end());
cout << "Número invertido: " << num << endl;
return 0;
}
*/
.section .data
msg_input: .asciz "Ingresa un número: "
msg_output: .asciz "Número invertido: "
msg_error: .asciz "Error en la entrada.\n"
.section .bss
input: .skip 12 // Espacio para el número (máx 11 dígitos + '\n' + null)
.section .text
.global _start
_start:
// 1. Mostrar mensaje de entrada
mov x0, 1 // File descriptor 1 (stdout)
ldr x1, =msg_input // Dirección del mensaje
mov x2, 18 // Longitud del mensaje
mov x8, 64 // syscall write
svc 0 // Llamar al sistema
// 2. Leer número desde stdin
mov x0, 0 // File descriptor 0 (stdin)
ldr x1, =input // Dirección del buffer
mov x2, 12 // Tamaño máximo de entrada
mov x8, 63 // syscall read
svc 0 // Llamar al sistema
// Verificar si la lectura falló (x0 < 1)
cmp x0, 1
blt error_exit // Si x0 < 1, error de lectura
// 3. Encontrar longitud del número sin incluir '\n'
ldr x1, =input // Dirección base del buffer
mov x2, 0 // Contador de longitud
find_length:
ldrb w3, [x1, x2] // Cargar byte actual
cmp w3, 10 // ¿Es '\n'?
beq remove_newline // Si sí, terminar conteo
cmp x2, 10 // ¿Máximo permitido?
bge remove_newline // Si sí, cortar aquí
add x2, x2, 1 // Incrementar contador
b find_length // Repetir
remove_newline:
mov w3, 0 // Reemplazar '\n' con null '\0'
strb w3, [x1, x2]
// 4. Invertir la cadena
sub x2, x2, 1 // Posición final válida
mov x4, 0 // Índice inicial
ldr x1, =input // Dirección base
reverse:
cmp x4, x2 // ¿Índices se cruzaron?
bge print_result // Si sí, saltar a imprimir
ldrb w5, [x1, x4] // Leer inicio
ldrb w6, [x1, x2] // Leer fin
strb w6, [x1, x4] // Intercambiar
strb w5, [x1, x2] // Intercambiar
add x4, x4, 1 // Avanzar inicio
sub x2, x2, 1 // Retroceder fin
b reverse // Repetir
print_result:
// 5. Agregar '\n' al final
add x2, x4, 1 // Posición después del último caracter
mov w3, 10 // '\n'
strb w3, [x1, x2]
// 6. Imprimir mensaje de salida
mov x0, 1 // stdout
ldr x1, =msg_output // Dirección del mensaje
mov x2, 18 // Longitud del mensaje
mov x8, 64 // syscall write
svc 0
// 7. Imprimir número invertido
mov x0, 1 // stdout
ldr x1, =input // Dirección del buffer
add x2, x4, 2 // Longitud real + '\n'
mov x8, 64 // syscall write
svc 0 // Llamar al sistema
// 8. Salir
mov x8, 93 // syscall exit
mov x0, 0 // Código de salida 0
svc 0 // Llamar al sistema
error_exit:
mov x0, 1 // stdout
ldr x1, =msg_error // Dirección del mensaje de error
mov x2, 21 // Longitud del mensaje
mov x8, 64 // syscall write
svc 0
mov x8, 93 // syscall exit
mov x0, 1 // Código de salida de error
svc 0 // Salir