/*
Autor: Victor Manuel Madrid Lugo
Fecha: 09/04/2025
Descripción: Calcula el doble de un número ingresado por el usuario y muestra el resultado.
Demostración: [https://asciinema.org/a/KAtrTNP8D9OSov5ACkbnqaEne]
Equivalente en Python:
numero = int(input("Ingrese un número: "))
print("El doble es:", numero * 2)
*/
.section .data
msg_prompt: .asciz "Ingrese un número: "
msg_result: .asciz "El doble es: "
newline: .asciz "\n"
buffer: .skip 21 // Buffer para entrada
result_str: .skip 21 // Buffer para resultado
.section .text
.global _start
_start:
// Mostrar mensaje
mov x0, #1
ldr x1, =msg_prompt
mov x2, #19 // Longitud de msg_prompt
mov x8, #64 // syscall write
svc #0
// Leer entrada
mov x0, #0
ldr x1, =buffer
mov x2, #21 // Tamaño del buffer
mov x8, #63 // syscall read
svc #0
// Convertir a entero
ldr x0, =buffer
bl atoi
mov x19, x0 // Guardar número en x19
// Calcular doble
lsl x20, x19, #1 // x20 = x19 * 2 (shift left 1 bit)
// Convertir resultado a string
ldr x0, =result_str
mov x1, x20
bl int_to_str
mov x21, x0 // Guardar longitud
// Mostrar resultado
mov x0, #1
ldr x1, =msg_result
mov x2, #13 // Longitud de msg_result
mov x8, #64
svc #0
mov x0, #1
ldr x1, =result_str
mov x2, x21 // Longitud del número
mov x8, #64
svc #0
// Nueva línea
mov x0, #1
ldr x1, =newline
mov x2, #1
mov x8, #64
svc #0
// Salir
mov x0, #0
mov x8, #93
svc #0
// Función atoi: Convierte string a entero
atoi:
mov x1, #0 // Resultado
mov x3, #10 // Base 10
mov x4, #0 // Indicador negativo
// Verificar signo
ldrb w2, [x0], #1
cmp w2, #'-'
b.ne atoi_loop
mov x4, #1
ldrb w2, [x0], #1
atoi_loop:
// Verificar fin de string
cmp w2, #10 // '\n'
beq atoi_done
cbz w2, atoi_done // '\0'
// Verificar dígito
cmp w2, #'0'
b.lt atoi_error
cmp w2, #'9'
b.gt atoi_error
// Convertir y acumular
sub w2, w2, #'0'
mul x1, x1, x3
add x1, x1, x2
// Siguiente carácter
ldrb w2, [x0], #1
b atoi_loop
atoi_done:
// Aplicar signo
cbz x4, atoi_positive
neg x1, x1
atoi_positive:
mov x0, x1
ret
atoi_error:
mov x0, #0
ret
// Función int_to_str: Convierte entero a string
int_to_str:
mov x2, #10
mov x3, #0 // Contador dígitos
mov x4, x0 // Guardar dirección buffer
// Manejar 0
cbz x1, handle_zero
// Manejar negativos
cmp x1, #0
b.gt positive
neg x1, x1
mov w5, #'-'
strb w5, [x4], #1
add x3, x3, #1
positive:
// Convertir dígitos
convert_loop:
udiv x5, x1, x2 // x5 = x1 / 10
msub x6, x5, x2, x1 // x6 = x1 % 10
add x6, x6, #'0'
strb w6, [x4, x3]
add x3, x3, #1
mov x1, x5
cbnz x1, convert_loop
// Invertir dígitos
mov x5, #0 // inicio
sub x6, x3, #1 // fin
reverse_loop:
cmp x5, x6
b.ge reverse_done
ldrb w7, [x4, x5]
ldrb w8, [x4, x6]
strb w8, [x4, x5]
strb w7, [x4, x6]
add x5, x5, #1
sub x6, x6, #1
b reverse_loop
handle_zero:
mov w5, #'0'
strb w5, [x4]
mov x3, #1
reverse_done:
// Null terminator
mov w5, #0
strb w5, [x4, x3]
mov x0, x3 // Devolver longitud
ret