Interface graphique minimale en assembleur x86-64 avec X11 : Optimisation pour fasmg
Les développeurs de code bas niveau sont souvent confrontés au défi de minimiser la taille des fichiers exécutables tout en conservant les fonctionnalités. Cet article explore la création d'une interface graphique minimale en assembleur x86-64 en utilisant le protocole X11. Nous utilisons fasmg pour générer un binaire compact sans éditeur de liens, mmap pour l'allocation dynamique de mémoire et des macros pour simplifier les appels système.
L'objectif est une fenêtre graphique avec du texte, plus petite que les implémentations originales. L'accent est mis sur la lisibilité du code pour les développeurs de niveau intermédiaire à senior : structures de requêtes X11, compatibilité ABI et optimisation de la copie des données.
Configuration de l'environnement de développement
Compilation dans VSCode avec des tâches pour les modes release et debug. Release : DEBUG=0, debug : DEBUG=1 avec génération de symboles DWARF.
{
"label": "Créer l'exécutable de release",
"type": "shell",
"command": "chmod",
"args": ["+x", "${fileBasenameNoExtension}"],
"dependsOn": "Compilation release avec fasmg"
}
Débogage dans Cutter avec launch.json :
{
"name": "Lancer Cutter",
"type": "node",
"request": "launch",
"preLaunchTask": "Compilation debug avec fasmg",
"runtimeExecutable": "Cutter.AppImage",
"runtimeArgs": [
"${fileDirname}/${fileBasenameNoExtension}",
"--analysis", "2",
"--arch", "x86",
"--bits", "64"
]
}
Appuyez sur Ctrl+Maj+T pour les compilations debug (fichiers .asm).
Macros pour le débogage et la journalisation
Liaison dynamique avec libc uniquement en mode debug :
include 'dynamic/import64.inc'
if DEBUG
interpreter '/lib64/ld-linux-x86-64.so.2'
needed 'libc.so.6'
import printf
end if
Macros pour printf à arguments variables avec support de %d, %f, %e, %g, %a. COUNT_ARGS_TO compte les arguments, GET_VARARG_TO les récupère par index.
Conversion float/double en IEEE-754 via la mémoire virtuelle 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 principale VARG_FUNC analyse la chaîne de format, distribuant les arguments aux registres selon l'ABI System V (xmm0-xmm7 pour les flottants, rsi/rdx/... pour les entiers). DEBUG_MSG est un wrapper pour les logs.
Structures de requêtes X11
Une structure FULL_LAYOUT unifiée contient toutes les requêtes nécessaires :
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
Les champs sont ordonnés pour minimiser le code de copie. Layout dans r12, sockets dans r13+.
Macro universelle d'appel système
MAKE_SYSCALL automatise la configuration des registres (rdi, rsi, rdx, r10, r8, r9) avec support pour 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
; similaire pour rsi, rdx, r10...
end iterate
; syscall scall
end macro
Optimisations de taille et de performance
- mmap au lieu de données statiques : page de 4 Ko pour toutes les structures X11.
- movsb pour la copie : regrouper les champs minimise les appels.
- Registres pour les constantes : r12-r15 restent inchangés.
- Valeurs par défaut dans le binaire : les macros génèrent uniquement les champs utilisés.
- Police fixe : X11 sélectionne automatiquement "fixed".
Avantages de fasmg : code compact, macros, pas d'éditeur de liens.
Points clés à retenir
- Les structures de requêtes X11 sont ordonnées pour une copie movsb optimale.
- Macro printf à arguments variables avec conversion IEEE-754 via mémoire virtuelle.
- Macro d'appel système universelle réduit le code répétitif de 70 %.
- mmap 4 Ko couvre toutes les structures sans données statiques dans le binaire.
- Compilations debug/release dans VSCode + Cutter pour le reverse engineering.
— Editorial Team
Aucun commentaire pour le moment.