GNU/Linux xterm bash 99 views

📌 Demostración: Conteo hacia atrás desde un número dado en ARM64 Assembly

💻 Lenguajes de Interfaz en TECNM Campus ITT
👨‍💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/09

🎯 Descripción

Este programa cuenta hacia atrás desde un número dado en memoria.
La implementación se realiza en:

Assembly ARM64 para RaspbianOS en Raspberry Pi

🔧 Compilación en Raspberry Pi (ARM64)

as conteo_atras.s -o conteo_atras.o  
ld conteo_atras.o -o conteo_atras

▶️ Ejecución

./conteo_atras

👀 Código fuente

🔗 Código fuente en Gist: Programa 24 Conteo hacia atrás desde un número dado Código Assembly ARM64 para RaspbianOS

/*
 ______  ____               ____  __ __      
/\  _  \/\  _`\   /'\_/`\  /'___\/\ \\ \     
\ \ \L\ \ \ \L\ \/\      \/\ \__/\ \ \\ \    
 \ \  __ \ \ ,  /\ \ \__\ \ \  _``\ \ \\ \_  
  \ \ \/\ \ \ \\ \\ \ \_/\ \ \ \L\ \ \__ ,__\
   \ \_\ \_\ \_\ \_\ \_\\ \_\ \____/\/_/\_\_/
    \/_/\/_/\/_/\/ /\/_/ \/_/\/___/    \/_/  
                                             
♡ ∩_∩ 
(„• ֊ •„)♡
| ̄U U ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄| 
| • Lenguajes de Interfaz en TECNM Campus ITT                            |   
| • Autor: Alejandro Suarez Sandoval                                     | 
| • Fecha: 2025/04/09                                                    | 
| • Descripción: Programa que cuenta hacia atrás desde un                | 
|   número dado en Python y Assembly ARM64 para RaspbianOS.              | 
| • Demostración:                                                        |
|   https://asciinema.org/a/713454                                       |
| • Compilación (Raspberry Pi ARM64):                                    |  
|     as conteo_atras.s -o conteo_atras.o                                |  
|     ld conteo_atras.o -o conteo_atras                                  |  
| • Ejecución: ./conteo_atras                                            |  
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄                                        

⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje Python •°•═══════

def cuenta_atras(numero_inicial):
    print(f"Cuenta atrás desde: {numero_inicial}\n")
    
    for i in range(numero_inicial, -1, -1):
        print(i)

if __name__ == "__main__":
    numero_inicial = 10
    cuenta_atras(numero_inicial)

════════════════════•°• ☆ •°•══════════════════════════════
/*

/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */

.data
numero_inicial: .quad   10              // Número desde el que empezará la cuenta atrás

msg_intro:      .ascii  "Cuenta atrás desde: "
msg_len_intro = . - msg_intro

msg_fin:        .ascii  "¡Cuenta regresiva completada!\n"
msg_len_fin = . - msg_fin

newline:        .ascii  "\n"
nl_len = . - newline

buffer:         .space  20              // Buffer para convertir enteros a ASCII

.text
.global _start

_start:
    // Mostrar mensaje introductorio
    mov x0, #1                      // file descriptor: 1 es stdout
    ldr x1, =msg_intro              // puntero al mensaje
    ldr x2, =msg_len_intro          // longitud del mensaje
    mov x8, #64                     // syscall: write = 64
    svc #0                          // llamada al sistema

    // Convertir y mostrar el número inicial
    ldr x0, =numero_inicial
    ldr x0, [x0]
    bl int_to_ascii
    mov x0, #1
    ldr x1, =buffer
    mov x2, x9                      // x9 contiene la longitud del string
    mov x8, #64
    svc #0

    // Mostrar nueva línea
    mov x0, #1
    ldr x1, =newline
    ldr x2, =nl_len
    mov x8, #64
    svc #0

    // Iniciar la cuenta atrás
    ldr x19, =numero_inicial
    ldr x19, [x19]                  // x19 = número inicial

bucle_cuenta_atras:
    // Convertir y mostrar el número actual
    mov x0, x19
    bl int_to_ascii
    
    mov x0, #1
    ldr x1, =buffer
    mov x2, x9
    mov x8, #64
    svc #0
    
    // Mostrar nueva línea
    mov x0, #1
    ldr x1, =newline
    ldr x2, =nl_len
    mov x8, #64
    svc #0
    
    // Decrementar contador
    subs x19, x19, #1
    
    // Si el resultado es negativo (-1), terminar
    bmi fin
    
    // Continuar con el bucle
    b bucle_cuenta_atras

fin:
    // Mostrar mensaje final
    mov x0, #1
    ldr x1, =msg_fin
    ldr x2, =msg_len_fin
    mov x8, #64
    svc #0
    
    // Salir del programa
    mov x0, #0                      // estado de salida: 0
    mov x8, #93                     // syscall: exit = 93
    svc #0

// Función para convertir un entero en x0 a ASCII en buffer
// Retorna en x9 la longitud del string
int_to_ascii:
    // Limpiar el buffer primero
    ldr x11, =buffer
    mov x12, #0
    
clear_buffer:
    cmp x12, #20
    beq clear_done
    strb wzr, [x11, x12]
    add x12, x12, #1
    b clear_buffer
    
clear_done:
    mov x10, #0         // contador de dígitos
    ldr x3, =buffer
    add x3, x3, #19     // apuntar al final del buffer
    mov x2, #10         // divisor = 10
    
    // Caso especial para 0
    cmp x0, #0
    bne convert_loop
    mov x4, #'0'        // ASCII de '0'
    strb w4, [x3]       // almacenar en buffer
    mov x9, #1          // longitud = 1
    b int_to_ascii_end

convert_loop:
    cbz x0, convert_end   // si x0 = 0, terminar
    udiv x1, x0, x2       // x1 = x0 / 10
    msub x4, x1, x2, x0   // x4 = x0 - (x1 * 10) = x0 % 10
    add x4, x4, #'0'      // convertir a ASCII
    strb w4, [x3], #-1    // guardar y mover el puntero
    add x10, x10, #1      // incrementar contador
    mov x0, x1            // x0 = x0 / 10
    b convert_loop

convert_end:
    add x3, x3, #1        // ajustar el puntero al primer dígito
    ldr x5, =buffer
    add x5, x5, #20
    sub x5, x5, x10       // x5 = dirección final en buffer
    
    // Copiar al principio del buffer
    ldr x6, =buffer
    mov x7, #0            // contador

copy_loop:
    cmp x7, x10
    beq copy_end
    ldrb w4, [x5, x7]     // cargar byte
    strb w4, [x6, x7]     // almacenar byte
    add x7, x7, #1        // incrementar contador
    b copy_loop

copy_end:
    mov x9, x10           // retornar longitud
    
int_to_ascii_end:
    ret