assembly nasm gas

assembly - ¿Cómo generar binarios simples como nasm-f bin con el ensamblador GNU GAS?



(2)

Tengo algunos archivos NASM que generalmente tienen la estructura:

[BITS 64] [ORG 0x0000000000200000] start: ... ret

Los estoy armando así:

nasm -f bin abc.asm

Me gustaría escribir algunos de estos usando GAS en su lugar. Dos preguntas:

  • ¿Qué directivas debería usar en GAS? Encontré la directiva ''.org'' pero GAS no parece tener una directiva ''.bits''.

  • ¿Qué debería pasar a gcc o generar un archivo binario simple? Es decir, lo que la opción -f bin hace con NASM.


¿Qué directivas debería usar en GAS? Encontré la directiva ''.org'' pero GAS no parece tener una directiva ''.bits''.

El ensamblador predeterminado para 64 bits para mí, puede usar --32 o --64 para elegir en la línea de comandos. Eche un vistazo al manual 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 gestor de arranque).

Lo más probable es que no desee utilizar la directiva .org para especificar dónde se encuentra el código, pero probablemente quiera utilizar 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é debería pasar a gcc o generar un archivo binario simple? Es decir, lo que la opción -f bin hace 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:

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


objcopy -O binario

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://.com/a/32960272/895245

Secuencia de comandos de enlace

-Ttext está bien para pruebas rápidas y sucias, pero para un trabajo serio, debes usar una secuencia de comandos para aumentar la robustez.

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

Sin más información, la secuencia de comandos mínima que puedo dar es:

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

Y luego usarlo 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.

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