No olvides que en las ciencias cualquier problema suele tener diferentes resoluciones, así que nosotros te enseñaremos lo más óptimo y mejor.
Solución:
Hay algunas posibilidades… aquí hay un par que se me ocurren:
-
Puede acceder a él en relación con una etiqueta que viene después la
.byte
directiva. Ejemplo:.byte 0x0a label: mov (label - 1), %eax
-
Basado en el diseño enlazado final del programa, tal vez el
.byte
Las directivas se ejecutarán como código. Aunque normalmente también tendrías una etiqueta en este caso… -
Algunos ensambladores no admiten la generación de prefijos de instrucciones x86 para el tamaño del operando, etc. En el código escrito para esos ensambladores, a menudo verá algo como:
.byte 0x66 mov $12, %eax
Para hacer que el ensamblador emita el código que desea tener.
Aquí hay un ejemplo con ensamblaje en línea:
#include
void main()
int dst;
// .byte 0xb8 0x01 0x00 0x00 0x00 = mov $1, %%eax
asm (".byte 0xb8, 0x01, 0x00, 0x00, 0x00nt"
"mov %%eax, %0"
: "=r" (dst)
: : "eax" // tell the compiler we clobber eax
);
printf ("dst value : %dn", dst);
return;
(Consulte la salida del compilador asm y también el desensamblaje del binario final en el explorador del compilador Godbolt).
Puedes reemplazar .byte 0xb8, 0x01, 0x00, 0x00, 0x00
con mov $1, %%eax
el resultado de la ejecución será el mismo. Esto indicó que puede ser un byte que puede representar alguna instrucción, por ejemplo, mover u otras.
Ejemplo ejecutable mínimo
.byte
escupe bytes donde quiera que estés. Si hay una etiqueta o no apunta al byte, no importa.
Si se encuentra en el segmento de texto, ese byte podría ejecutarse como código.
Carl lo mencionó, pero aquí hay un ejemplo completo para dejar que se hunda más: una implementación de Linux x86_64 de true
con un nop
tirado en:
.global _start
_start:
mov $60, %rax
nop
mov $0, %rdi
syscall
produce exactamente el mismo ejecutable que:
.global _start
_start:
mov $60, %rax
.byte 0x90
mov $0, %rdi
syscall
ya que nop
se codifica como el byte 0x90
.
Un caso de uso: nuevas instrucciones
Un caso de uso es cuando se agregan nuevas instrucciones a una CPU ISA, pero solo las versiones muy avanzadas del ensamblador lo admitirían.
Por lo tanto, los mantenedores del proyecto pueden optar por alinear los bytes directamente para hacerlo compilable en ensambladores más antiguos.
Vea, por ejemplo, esta solución de Spectre en el kernel de Linux con el análogo .inst
directiva: https://github.com/torvalds/linux/blob/94710cac0ef4ee177a63b5227664b38c95bbf703/arch/arm/include/asm/barrier.h#L23
#define CSDB ".inst 0xe320f014"
Se agregó una nueva instrucción para Spectre, y el kernel decidió codificarla por el momento.
Si te animas, eres capaz de dejar un escrito acerca de qué le añadirías a este escrito.