Me topé con una practica curiosa, que me hizo aprender bastante acerca de las partes bajas y altas de los registros. El tema es que me solicitaban que cierto código ensamblador proporcionado en una actividad ocupase menos de 50 bytes en código maquina y no contuviese ceros. Por lo que tuve que trastear con aprovechar al máximo los registros y usar los mas pequeños posibles.
También aprendí que setear a 0 un registro es mas costoso en bytes que hacer «xor registro, registro».
Y con esas dos cosillas, y suprimir la llamada a exit por ahorrar unos bytes… voilá.
¿Serías capaz de bajar más los bytes de código maquina sin perder funcionalidad?

Registro | Descripción | Parte baja | Parte alta |
rax | Acumulador, se usa para operaciones aritméticas, syscalls | al (8 bits) | ah (8 bits) |
rbx | Usado para operaciones generales, no se suele tocar en syscalls | bl (8 bits) | bh (8 bits) |
rcx | Contador, se usa para ciclos y desplazamientos | cl (8 bits) | ch (8 bits) |
rdx | Usado para operaciones de multiplicación, división y para syscalls | dl (8 bits) | dh (8 bits) |
rdi | Primer argumento para syscalls (y funciones C) | dil (8 bits) | |
rsi | Segundo argumento para syscalls (y funciones C) | sil (8 bits) | |
rbp | Puntero a la base del marco de la pila (stack frame) | bpl (8 bits) | |
rsp | Puntero a la cima de la pila | ||
r8 – r15 | Registros adicionales para usar en funciones o syscalls | r8b – r15b (8 bits) | r8w – r15w (16 bits) |