GNU/Linux xterm bash 165 views

Este código en ARM64 tiene como objetivo convertir un número entero en una cadena ASCII y luego imprimirla en la consola, repitiendo este proceso para varios números dentro de un rango. Vamos a desglosar el código paso a paso:

1. Sección de datos

.section .data
buffer: .skip 16  // Espacio para la cadena del número y salto de línea
  • buffer: Se reserva espacio de 16 bytes para almacenar una cadena que contiene el número convertido y un salto de línea. El buffer se usa para almacenar la representación en texto del número entero.

2. Sección de texto (código)

.section .text
.global _start
  • Se define la sección de código (.text) y se declara la etiqueta _start como global, lo que indica el punto de entrada del programa.

3. Inicio del programa (_start)

_start:
    mov x19, #7                 // x19 = contador (i = 7)
  • x19: Se inicializa el contador con el valor 7. Este valor representará el número inicial que se convertirá en cadena y se imprimirá en la consola.

4. Bucle principal (loop)

loop:
    // Convertir entero a cadena (itoa)
    mov x0, x19                 // x0 = número a convertir
    ldr x1, =buffer             // x1 = puntero al buffer
    bl int_to_str               // llama a la rutina para convertir número
  • En el inicio de cada iteración del bucle, se mueve el valor del contador (x19) a x0, que es el primer argumento para la subrutina int_to_str.
  • Luego se carga la dirección del buffer en x1 y se llama a la subrutina int_to_str para convertir el número en una cadena ASCII.

5. Imprimir el número convertido

    // Escribir en consola
    mov x8, #64                 // syscall write
    mov x0, #1                  // file descriptor 1 (stdout)
    ldr x1, =buffer             // puntero a la cadena
    mov x2, #3                  // longitud fija (2 dígitos + '\n')
    svc #0
  • x8 = 64: Prepara la llamada al sistema para la función write, que se utiliza para escribir en la consola.
  • x0 = 1: Especifica que la salida se enviará a la consola estándar (stdout).
  • x1: Carga la dirección del buffer, que contiene la cadena del número.
  • x2 = 3: Se especifica la longitud de la cadena, que en este caso es siempre 3: dos dígitos para el número y un salto de línea al final.
  • svc #0: Realiza la llamada al sistema para escribir en la consola.

6. Incrementar contador y continuar el bucle

    // Incrementar contador
    add x19, x19, #2            // i += 2
    cmp x19, #51
    ble loop                    // Mientras i <= 51, continuar
  • Se incrementa el valor del contador (x19) en 2 al final de cada iteración.
  • cmp x19, #51: Compara el valor de x19 con 51.
  • ble loop: Si x19 es menor o igual a 51, se vuelve a ejecutar el bucle.

7. Salir del programa

// Salir del programa
    mov x8, #93                 // syscall exit
    mov x0, #0                  // status 0
    svc #0
  • x8 = 93: Prepara la llamada al sistema para salir del programa (código de salida 93).
  • x0 = 0: Especifica que el estado de salida será 0 (indicado como “exit status”).
  • svc #0: Realiza la llamada al sistema para salir del programa.

8. Subrutina: int_to_str (convertir entero a cadena)

// ----------------------------------
// Rutina: int_to_str
// Entrada: x0 = entero, x1 = puntero al buffer
// Salida: cadena ASCII en buffer terminada con '\n'
// ----------------------------------
int_to_str:
    // convierte entero de 2 dígitos a texto
    // x0 = valor entero
    // x1 = buffer

    // dividir por 10
    mov x2, #10
    udiv x3, x0, x2             // x3 = cociente (dígito alto)
    msub x4, x3, x2, x0         // x4 = residuo (dígito bajo)

    add x3, x3, #'0'            // convertir a ASCII
    add x4, x4, #'0'

    strb w3, [x1]               // guardar primer carácter
    strb w4, [x1, #1]           // segundo carácter
    mov w5, #'\n'
    strb w5, [x1, #2]           // salto de línea
    ret
  • int_to_str: Esta subrutina convierte un número entero (de 2 dígitos) en una cadena de caracteres ASCII. La entrada es un número entero en x0, y la salida es la cadena convertida en el buffer apuntado por x1.Paso a paso:
    1. División por 10: Se divide el número entre 10 usando la instrucción udiv, lo que da como resultado el dígito más significativo (almacenado en x3) y el dígito menos significativo (almacenado en x4).
    2. Conversión a ASCII: Se suman los valores ASCII correspondientes a los dígitos y se almacenan en el buffer.
    3. Se agrega un salto de línea (\n) al final de la cadena.
    4. La subrutina termina con la instrucción ret, lo que regresa el control al código que llamó a la subrutina.

Resumen general:

Este programa imprime los números 7, 9, 11, ..., 49 en la consola, uno por línea, en formato de dos dígitos seguidos de un salto de línea. Para cada número:

  • Se convierte el número a una cadena ASCII.
  • Se imprime esa cadena en la consola.
  • El número se incrementa en 2 y el proceso se repite hasta llegar a 51.

El código utiliza llamadas al sistema para la escritura en consola y la salida del programa, así como una rutina personalizada (int_to_str) para convertir los números a texto.