如何在16位模式下使用GDB?

sar*_*hak 4 c x86 assembly gdb

我有以下代码,我试图实现一个使用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;
}
Run Code Online (Sandbox Code Playgroud)

函数中断在汇编中实现.它调用适当的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
Run Code Online (Sandbox Code Playgroud)

由于我使用BIOS中断,我使用16位模式来编译此代码.我使用以下命令:

bcc -ansi -c -o printString.o printString.c
Run Code Online (Sandbox Code Playgroud)

我想在GDB中测试这段代码,但是当我尝试使用以下命令将此printString.o文件加载到gdb中时:

gdb printString.o
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

"/home/kern/printString.o":不是可执行格式:无法识别文件格式

我还尝试使用以下方法将GDB更改为16位格式:

set architecture i8086
Run Code Online (Sandbox Code Playgroud)

但是这个错误仍然存​​在.如何将16位代码加载到GDB中?

Cir*_*四事件 6

最小的QEMU示例

qemu-system-i386 -hda main.img -S -s &
gdb -ex 'target remote localhost:1234' \
    -ex 'set architecture i8086' \
    -ex 'break *0x7c00' \
    -ex 'continue'
Run Code Online (Sandbox Code Playgroud)

哪个main.img引导扇区.

  • break *0x7c00:第一条指令不是你的启动扇区,而是0x0000fff0BIOS设置,也参见.因此我们使用它从引导扇区加载到的位置开始.
  • set architecture i8086:对于常规的ELF可执行文件,GDB可以从头文件中决定体系结构.但是对于原始引导扇区,没有这样的元数据,所以我们必须告诉它.

也可以看看:


Par*_*ani 5

正如 Jester 在评论中所说,您不能使用gdb.

并且你不能运行 16 位可执行文件或 16 位汇编代码gdb。您必须使用类似qemu在模拟 CPU上运行您的代码并使用连接到它的东西gdb,或者您可以使用dosbox它来运行您的代码并在 DOS 上使用调试程序。请记住,在现代操作系统(如 Linux)上使用 BIOS 中断是错误的,因为这些操作系统在启动时会禁用 BIOS 中断。


归档时间:

查看次数:

2879 次

最近记录:

7 年,6 月 前