Volver al inicio

Ensamblador x86-64 GUI X11 fasmg

El artículo describe la creación de una GUI mínima en ensamblador x86-64 con protocolo X11 usando fasmg. Se discuten macros para printf vararg, llamadas al sistema y optimización de estructuras para mmap. Detalles sobre compilación debug/release en VSCode y depuración en Cutter.

GUI mínima en ensamblador: X11 + optimización fasmg
Advertisement 728x90

Interfaz Gráfica Mínima en Ensamblador x86-64 con X11: Optimización para fasmg

Los desarrolladores de código de bajo nivel a menudo enfrentan el desafío de minimizar el tamaño del archivo ejecutable manteniendo la funcionalidad. Este artículo explora la creación de una interfaz gráfica mínima en ensamblador x86-64 utilizando el protocolo X11. Usamos fasmg para generar un binario compacto sin enlazador, mmap para asignación dinámica de memoria y macros para simplificar las llamadas al sistema.

El objetivo es una ventana gráfica con texto, más pequeña que las implementaciones originales. El enfoque está en la legibilidad del código para desarrolladores de nivel medio a senior: estructuras de solicitud X11, compatibilidad ABI y optimización de copia de datos.

Configuración del Entorno de Desarrollo

Compilación en VSCode con tareas para modos de lanzamiento y depuración. Lanzamiento: DEBUG=0, depuración: DEBUG=1 con generación de símbolos DWARF.

Google AdInline article slot
{
    "label": "Crear ejecutable de lanzamiento",
    "type": "shell",
    "command": "chmod",
    "args": ["+x", "${fileBasenameNoExtension}"],
    "dependsOn": "Compilación de lanzamiento con fasmg"
}

Depuración en Cutter con launch.json:

{
    "name": "Lanzar Cutter",
    "type": "node",
    "request": "launch",
    "preLaunchTask": "Compilación de depuración con fasmg",
    "runtimeExecutable": "Cutter.AppImage",
    "runtimeArgs": [
        "${fileDirname}/${fileBasenameNoExtension}",
        "--analysis", "2",
        "--arch", "x86",
        "--bits", "64"
    ]
}

Presiona Ctrl+Shift+T para compilaciones de depuración (archivos .asm).

Macros para Depuración y Registro

Enlazar libc dinámicamente solo en modo depuración:

Google AdInline article slot
include 'dynamic/import64.inc'
if DEBUG
    interpreter '/lib64/ld-linux-x86-64.so.2'
    needed 'libc.so.6'
    import printf
end if

Macros para printf con argumentos variables con soporte para %d, %f, %e, %g, %a. COUNT_ARGS_TO cuenta argumentos, GET_VARARG_TO los recupera por índice.

Convertir float/double a IEEE-754 mediante memoria virtual de fasm:

macro MOVQ_IMM reg, val
    local bits
    virtual at 0
        dq val
        load bits qword from 0
    end virtual
    mov rax, bits
    movq reg, rax
end macro

La macro principal VARG_FUNC analiza la cadena de formato, distribuyendo argumentos a registros según la ABI System V (xmm0-xmm7 para float, rsi/rdx/... para entero). DEBUG_MSG es un envoltorio para registros.

Google AdInline article slot

Estructuras de Solicitud X11

Una estructura FULL_LAYOUT unificada contiene todas las solicitudes necesarias:

struct FULL_LAYOUT
    ridBase             dd  0
    ridMask             dd  0
    windowRootId        dd  0
    rootVisualId        dd  0
    gcId                dd  0
    exposed             db  0
    create_window_req   X11_CREATE_WINDOW
    draw_string_req     STRING_TO_DRAW
    handshake           X11_HANDSHAKE
    gc_request          X11_CREATE_GC
    addr_un             SOCKADDR_UN
    map_window_req      X11_MAP_WINDOW
    union
        free    rb     HEAP_SIZE - ($ - create_window_req)
        setup   X11_SETUP
        pollfd  POLLFD
    endu
ends

Los campos están ordenados para minimizar el código de copia. Diseño en r12, sockets en r13+.

Macro Universal de Llamada al Sistema

MAKE_SYSCALL automatiza la configuración de registros (rdi, rsi, rdx, r10, r8, r9) con soporte para ptr [c], [c], 0:

macro MAKE_SYSCALL scall, args&
    iterate arg, args
        if % = 1
            match =ptr [c], arg
                lea    rdi, [c]
            else match [c], arg
                mov     rdi, [c]
            else match =0, arg
                xor    rdi, rdi
            else
                mov    rdi, arg
            end match
        ; similar para rsi, rdx, r10...
    end iterate
    ; syscall scall
end macro

Optimizaciones de Tamaño y Rendimiento

  • mmap en lugar de datos estáticos: página de 4KB para todas las estructuras X11.
  • movsb para copiar: agrupar campos minimiza llamadas.
  • Registros para constantes: r12-r15 permanecen sin cambios.
  • Valores predeterminados en binario: macros generan solo campos usados.
  • Fuente fija: X11 selecciona automáticamente "fixed".

Ventajas de fasmg: código compacto, macros, sin enlazador.

Conclusiones Clave

  • Las estructuras de solicitud X11 están ordenadas para copia óptima con movsb.
  • Macro printf con argumentos variables y conversión IEEE-754 mediante memoria virtual.
  • Macro universal de llamada al sistema reduce código repetitivo en un 70%.
  • mmap de 4KB cubre todas las estructuras sin datos estáticos en el binario.
  • Compilaciones de lanzamiento/depuración en VSCode + Cutter para ingeniería inversa.

— Editorial Team

Advertisement 728x90

Leer después