Saltar al contenido

¿Cuál es el uso de la directiva de ensamblador .byte en el ensamblaje gnu?

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:

  1. 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
    
  2. 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…

  3. 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *