GNU/Linux xterm bash 167 views

Este código está escrito en ensamblador ARM64 y tiene como objetivo imprimir en consola una tabla que muestra el valor de ( i ) junto con el valor de ( \frac{1}{i} ) para valores de ( i ) del 1 al 30. El programa utiliza la función printf para la impresión, y realiza algunas conversiones entre enteros, flotantes y dobles en el proceso.

Desglose detallado:

1. Sección de Datos (.data)

.section .data
    fmt:    .asciz "%d\t%f\n"
  • fmt: Define una cadena de formato para la función printf. La cadena es "%d\t%f\n", que indica que se imprimirán dos valores: un entero (%d) y un número en punto flotante (%f), seguidos de un salto de línea.

2. Sección de Texto (.text)

.section .text
.global main
  • Aquí comienza la sección de código, y main se declara como global, lo que significa que es el punto de entrada principal del programa.

3. Prologue (Guardar registros)

main:
    stp x29, x30, [sp, -16]!       // Prologue
  • stp x29, x30, [sp, -16]!: Guarda los registros x29 (frame pointer) y x30 (return address) en la pila antes de entrar al cuerpo principal de la función. Esto es para proteger el contexto de la función y permitir que se restaure correctamente al final.

4. Inicialización de Variables

    mov x19, #1                    // i = 1
  • mov x19, #1: Inicializa x19 con el valor 1, que será el contador del bucle. Este valor representa el valor de ( i ).

5. Bucle Principal (loop)

loop:
    cmp x19, #31                   // while (i <= 30)
    bge end
  • cmp x19, #31: Compara el valor de x19 (el contador ( i )) con 31.
  • bge end: Si x19 es mayor o igual a 31, salta a la etiqueta end, es decir, termina el bucle.
    scvtf s0, x19                  // s0 = (float)i
  • scvtf s0, x19: Convierte el valor entero de x19 a un número flotante y lo almacena en el registro s0. Este registro contiene la versión en punto flotante de ( i ).
    fmov s1, #1.0                  // s1 = 1.0
    fdiv s1, s1, s0                // s1 = 1.0 / i
  • fmov s1, #1.0: Mueve el valor 1.0 al registro de punto flotante s1.
  • fdiv s1, s1, s0: Realiza una división flotante ( \text{1.0} / i ), y almacena el resultado en s1.
    fcvt d0, s1                    // Convertir float a double
  • fcvt d0, s1: Convierte el valor de s1 (que es de tipo flotante) a tipo doble (double) y lo almacena en d0. Este paso es necesario porque la función printf espera un valor de tipo doble para imprimir números en punto flotante.
    ldr x0, =fmt                   // Formato para printf
    mov x1, x19                    // Entero a imprimir
    bl printf
  • ldr x0, =fmt: Carga la dirección de la cadena de formato fmt en x0.
  • mov x1, x19: Pone el valor de x19 (el contador ( i )) en x1.
  • bl printf: Llama a la función printf para imprimir los valores de x19 (el exponente) y d0 (el valor de ( \frac{1}{i} )) con el formato especificado.
    add x19, x19, #1               // Incrementar i
  • add x19, x19, #1: Incrementa x19 en 1, lo que corresponde a pasar al siguiente valor de ( i ) en el bucle.
    b loop
  • b loop: Regresa al inicio del bucle para verificar si ( i ) es menor o igual a 30. Si es así, repite el proceso.

6. Final del Bucle (end)

end:
    ldp x29, x30, [sp], 16         // Epilogue
    mov w0, #0                     // Código de salida 0
    ret
  • ldp x29, x30, [sp], 16: Restaura los registros x29 y x30 desde la pila. Esto es parte de la restauración del contexto de la función (epílogo).
  • mov w0, #0: Coloca el valor 0 en w0 como el código de salida del programa.
  • ret: Finaliza la función main y devuelve el control al sistema operativo.

Resumen del Funcionamiento:

  1. El programa inicializa el contador i en 1.
  2. Luego, entra en un bucle que continúa hasta que i alcanza 31.
  3. Dentro del bucle, convierte i a un valor flotante, calcula ( \frac{1}{i} ), lo convierte a tipo doble y luego lo imprime junto con i.
  4. Después de imprimir, i se incrementa y el proceso se repite hasta que i exceda 30.
  5. El programa termina correctamente con un código de salida 0.

Ejemplo de salida esperada:

1   1.000000
2   0.500000
3   0.333333
4   0.250000
5   0.200000
...
30  0.033333