Как использовать GDB в 16-битном режиме?
У меня есть следующий код, где я пытаюсь реализовать функцию, которая печатает строку с использованием функций BIOS:
int printString(char* string)
{
int i = 0;
while (*(string + i) != '\0')
{
char al = *(string + i);
char ah = 0xe;
int ax = ah * 256 + al;
interrupt(0x10,ax,0,0,0);
i++;
}
return i;
}
Функция прерывания реализована в сборке. Он вызывает соответствующее прерывание BIOS, заданное первым аргументом, с остальными аргументами, содержащими содержимое для регистров ax,bx,cx и dx соответственно:
.global _interrupt
_interrupt:
push bp
mov bp, sp
push si
push ds
mov ax, #0x100
mov ds, ax
mov ax, [bp + 0x4]
mov si, #intr
mov [si + 1], al
pop ds
mov ax, [bp + 0x6]
mov bx, [bp + 0x8]
mov cx, [bp + 0xa]
mov dx, [bp + 0xc]
intr: int #0x0
pop si
pop bp
ret
Поскольку я использую прерывания BIOS, я использую 16-битный режим для компиляции этого кода. Я использовал следующую команду:
bcc -ansi -c -o printString.o printString.c
Я хочу проверить этот код в GDB, но когда я пытаюсь загрузить этот файл printString.o в GDB, используя:
gdb printString.o
Я получаю следующую ошибку:
"/home/kern/printString.o": не в исполняемом формате: формат файла не распознан
Я также попытался изменить GDB на 16-битный формат, используя:
set architecture i8086
Но все же эта ошибка идет. Как я могу загрузить 16-битный код в GDB?
2 ответа
Как говорит Джестер в комментариях, вы не можете запустить объектный файл с gdb
,
И вы не можете запустить 16-битный исполняемый файл или 16-битный код сборки с gdb
, ты должен что-то вроде qemu
запустить ваш код на эмулируемом процессоре и подключиться к нему, используя gdb
или вы можете использовать dosbox
чтобы запустить ваш код и использовать программу отладки на дос. и помните, что использование прерываний BIOS является ошибкой современной ОС, такой как linux, потому что при запуске эти операционные системы отключают прерывания BIOS.
Минимальный пример QEMU
qemu-system-i386 -hda main.img -S -s &
gdb -ex 'target remote localhost:1234' \
-ex 'set architecture i8086' \
-ex 'break *0x7c00' \
-ex 'continue'
где main.img
загрузочный сектор
break *0x7c00
: первой инструкцией будет не ваш загрузочный сектор, а скорее0x0000fff0
который выполняет настройку BIOS, см. также. Поэтому мы используем это, чтобы начать с того места, куда загружается загрузочный сектор.set architecture i8086
: для обычных исполняемых файлов ELF GDB может выбирать архитектуру по заголовкам. Но для необработанных загрузочных секторов таких метаданных нет, поэтому мы должны сообщить об этом.
Смотрите также:
- Как получить информацию об отладке на уровне исходного кода: Как выполнить отладку кода на уровне исходного кода x86 с помощью GDB внутри QEMU?
- Похожие вопросы: Низкоуровневая отладка на основе qemu || Отладка QEMU с помощью GDB || Отладка загрузчика с помощью gdb в qemu
- Еще несколько хороших идей: /questions/39955432/kak-razobrat-16-bitnyij-kod-zagruzochnogo-sektora-x86-v-gdb-s-pomoschyu-xi-pc-eto-rassmatrivaetsya-kak-32-razryadnyij/39955450#39955450
- Как перешагнуть
int
: Как перешагнуть вызовы прерывания при отладке загрузчика / BIOS с помощью GDB и QEMU?