Как генерировать простые двоичные файлы, такие как nasm -f bin, с помощью GNU GAS ассемблера?
У меня есть несколько файлов NASM, которые обычно имеют структуру:
[BITS 64]
[ORG 0x0000000000200000]
start:
...
ret
Я собираю их так:
nasm -f bin abc.asm
Я хотел бы написать некоторые из них, используя вместо этого ГАЗ. Два вопроса:
Какие директивы я должен использовать в ГАЗЕ? Я нашел директиву.org, но GAS, похоже, не имеет директивы.bits.
Что я должен передать
gcc
или жеas
создать простой двоичный файл? То есть что-f bin
вариант делает с NASM.
2 ответа
Какие директивы я должен использовать в ГАЗЕ? Я нашел директиву.org, но GAS, похоже, не имеет директивы.bits.
По умолчанию ассемблер 64-битный для меня, вы можете использовать --32
или же --64
выбрать в командной строке. Взгляните на руководство, чтобы узнать, как вы можете изменить архитектуру внутри кода, если это необходимо (например, .code16
может использоваться для генерации кода реального режима для загрузчика).
Скорее всего, вы не хотите использовать .org
директива, указывающая, где находится код, но, вероятно, захочет использовать скрипт ссылки или указать, где текстовые сегменты и сегменты данных загружаются в командной строке. (org 0x0000000000200000
в результате получается бинарный файл размером 2+ МБ).
Что я должен передать gcc или как создать простой двоичный файл? То есть, что опция -f bin делает с 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 двоичный
Хороший вариант это:
as -o test.o test.S
ld -Ttext 0x7C00 -o test.elf test.o
objcopy -O binary kernel.elf kernel.bin
Преимущество над ld --oformat binary
в том, что для отладки проще использовать символы:
qemu-system-i386 -hda main.img -S -s &
gdb main.elf -ex 'target remote localhost:1234'
Скрипт компоновщика
-Ttext
подходит для быстрого и грязного тестирования, но для серьезной работы вы должны использовать вместо этого сценарий, чтобы повысить надежность.
Иначе, ld
будет использовать скрипт по умолчанию (ld --verbose
) предназначено для пользовательского приложения, которое не похоже на ваше приложение.
Без дополнительной информации, минимальный сценарий, который я могу дать:
SECTIONS
{
. = 2M;
.text :
{
*(.*)
}
}
А затем использовать его с -T
:
as --64 -o test.o test.S
ld -T linker.ld --oformat binary -o test.bin test.o
Но вы, вероятно, захотите изменить этот сценарий в соответствии с вашим конкретным приложением.
Смотрите также: Есть ли способ получить gcc для вывода необработанного двоичного файла?
У меня есть репозиторий с рабочими примерами для некоторых распространенных случаев использования: