GNU/Linux xterm bash 365 views

Este código ARM64 es un programa interactivo de conversión de unidades que usa printf y scanf para entrada/salida y realiza cálculos con números de punto flotante (double), incluyendo:

  • Pulgadas a yardas
  • Pies a pulgadas
  • Opción para salir

Vamos paso a paso para entenderlo todo:


🧾 Sección .rodata: Datos de solo lectura

.align 3
menu:       .asciz  "...texto del menú..."
prompt_in:  .asciz  "Ingrese el valor a convertir: "
fmt_in:     .asciz  "%lf"             // Formato para leer un double
result_iy:  .asciz  "%.2f pulgadas = %.4f yardas\n"
result_pi:  .asciz  "%.2f pies = %.2f pulgadas\n"
err_op:     .asciz  "Opción no válida..."
newline:    .asciz  "\n"

.align 3
inches_per_yard: .double 36.0
inches_per_foot: .double 12.0
  • Se definen cadenas que se usarán con printf y scanf.
  • Se incluyen dos constantes en formato double:
    • inches_per_yard = 36.0
    • inches_per_foot = 12.0
  • .align 3 asegura que los double estén alineados a 8 bytes.

🔁 Flujo del programa principal

.global main
main:
    stp x29, x30, [sp, -16]!   // Guarda registros de frame (stack frame)

🔁 Bucle del menú

menu_loop:
    ldr x0, =menu
    bl printf
  • Muestra el menú de opciones.

📥 Leer opción del usuario

    sub sp, sp, #16         // Reserva espacio en stack para un double
    mov x1, sp              // Dirección donde guardar la entrada
    ldr x0, =fmt_in         // "%lf"
    bl scanf

    ldr d0, [sp]            // Cargar el valor double ingresado
    fcvtzs w19, d0          // Convertir de float (double) a entero (opción)
    add sp, sp, #16         // Liberar stack
  • Lee un valor de punto flotante (double) y lo convierte a entero en w19.

🔍 Validar opción

    cmp w19, #3
    b.eq exit_program
    cmp w19, #1
    b.lt invalid_option
    cmp w19, #2
    b.gt invalid_option
  • Si la opción es 3, salta al final.
  • Si es menor que 1 o mayor que 2, es inválida.

📥 Leer el valor a convertir

    ldr x0, =prompt_in
    bl printf

    sub sp, sp, #16
    mov x1, sp
    ldr x0, =fmt_in
    bl scanf

    ldr d0, [sp]            // valor ingresado a convertir
    add sp, sp, #16

🔄 Procesar opción

1. 🟣 Pulgadas a yardas

inches_to_yards:
    adrp x0, inches_per_yard
    ldr d1, [x0, #:lo12:inches_per_yard]
    fdiv d1, d0, d1         // yardas = pulgadas / 36
    ldr x0, =result_iy
    bl printf
    b menu_loop
  • Divide el valor ingresado por 36 y lo imprime.

2. 🟢 Pies a pulgadas

feet_to_inches:
    adrp x0, inches_per_foot
    ldr d1, [x0, #:lo12:inches_per_foot]
    fmul d1, d0, d1         // pulgadas = pies * 12
    ldr x0, =result_pi
    bl printf
    b menu_loop
  • Multiplica por 12 y muestra el resultado.

❌ Opción inválida

invalid_option:
    ldr x0, =err_op
    bl printf
    b menu_loop

🛑 Salir del programa

exit_program:
    ldr x0, =newline
    bl printf

    mov w0, #0
    ldp x29, x30, [sp], 16
    ret
  • Imprime una línea en blanco y termina con ret.

📌 Notas Técnicas

  • adrp + ldr ... :lo12: es una técnica común en ARM64 para acceder a datos grandes (64 bits como double) desde direcciones de solo lectura.
  • fcvtzs: convierte double a int truncando decimales.
  • fdiv, fmul: operaciones de punto flotante.
  • bl printf / scanf: llamadas a funciones de C disponibles en tiempo de ejecución.

🧪 Ejemplo de ejecución

Menu de conversión:
1. Pulgadas a Yardas
2. Pies a Pulgadas
3. Salir
Seleccione opción: 1
Ingrese el valor a convertir: 72
72.00 pulgadas = 2.0000 yardas