¿Cómo generar binarios simples como NASM -F Bin con el ensamblador de gas GNU?

StackOverflow https://stackoverflow.com/questions/6828631

  •  26-10-2019
  •  | 
  •  

Pregunta

Tengo algunos archivos NASM que generalmente tienen la estructura:

        [BITS 64]
        [ORG 0x0000000000200000]

start:
        ...

        ret

Los estoy reuniendo así:

nasm -f bin abc.asm

En su lugar, me gustaría escribir algunos de estos usando gas. Dos preguntas:

  • ¿Qué directivas debo usar en gas? He encontrado la directiva '.org', pero el gas no parece tener una directiva '.bits'.

  • A que debo pasar gcc o as para generar un archivo binario simple? Es decir, que el -f bin La opción lo hace con NASM.

¿Fue útil?

Solución

¿Qué directivas debo usar en gas? He encontrado la directiva '.org', pero el gas no parece tener una directiva '.bits'.

El ensamblador predeterminado es 64-bit para mí, puede usar --32 o --64 para elegir en la línea de comando. Echa un vistazo al manual para como Para ver cómo puede cambiar la arquitectura dentro del código si es necesario (por ejemplo, .code16 se puede usar para generar código de modo real para un cargador de arranque).

Lo más probable es que no quiera usar el .org Directiva para especificar dónde se encuentra el código, pero probablemente quiera usar un script de enlace o especificar dónde se cargan los segmentos de texto y datos en la línea de comando. (org 0x0000000000200000 Resulta en un archivo binario de 2+ MB).

¿Qué debo pasar a GCC o para generar un archivo binario simple? Es decir, lo que hace la opción de bin -f con NASM.

$ cat test.S
.section .text
.globl _start
_start:
        xor %rax, %rax
        mov test, %rax
        ret

test: .quad 0x1234567812345678


$ as --64 -o test.o test.S
$ ld -Ttext 200000 --oformat binary -o test.bin test.o

$ objdump -D -b binary -m i386:x86-64 test.bin
test.bin:     file format binary
Disassembly of section .data:

000000000000000000 <.data>: 0: 48 31 C0 XOR%RAX,%RAX 3: 48 8B 04 25 0C 00 20 MOV 0X20000C,%RAX A: 00 B: C3 RETQ
C: 78 56 JS 0x64 E: 34 12 Xor $ 0x12,%Al 10: 78 56 JS 0x68 12: 34 12 Xor $ 0x12,%Al

Otros consejos

objcopy -O binary

Una buena opción es:

as -o test.o test.S
ld -Ttext 0x7C00 -o test.elf test.o
objcopy -O binary kernel.elf kernel.bin

La ventaja sobre ld --oformat binary es que es más fácil usar los símbolos para depurar a través de:

qemu-system-i386 -hda main.img -S -s &
gdb main.elf -ex 'target remote localhost:1234'

Ver también: https://stackoverflow.com/a/32960272/895245

Script de enlazador

-Ttext está bien para pruebas rápidas y sucias, pero para un trabajo serio debe usar un script para aumentar la robustez.

De lo contrario, ld utilizará un script predeterminado (ld --verbose) destinado a la aplicación Userland, que no se parece a su aplicación.

Sin más información, el script mínimo que puedo dar es:

SECTIONS
{
    . = 2M;
    .text :
    {
        *(.*)
    }
}

Y luego úsalo con -T:

as --64 -o test.o test.S
ld -T linker.ld --oformat binary -o test.bin test.o

Pero es probable que desee modificar ese script en función de su aplicación exacta.

Ver también: ¿Hay alguna forma de lograr que GCC emita un binario sin procesar?

Tengo un repositorio con ejemplos de trabajo para algunos casos de uso comunes:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top