GNU/Linux xterm-256color bash 185 views

/*
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