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

时间:2015-03-02 14:07:40

标签: c assembly x86 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;
}

函数中断在汇编中实现。它调用适当的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 个答案:

答案 0 :(得分:6)

最小QEMU示例

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class Project1 {
    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new FileReader("/Users/Ayesha/Desktop/inputfile.txt"));
        ArrayList<String> list = new ArrayList<String>();
        while (true) {
            String line = reader.readLine();
            if (line == null) {
                break;
            }
            System.out.println(line);
            list.add(line);
        }

        String data[] = list.toArray(new String[list.size()]);

        reader.close();

        for (int i = 0; i < data.length - 1; ++i) {
            int minIndex = i;
            for (int j = i + 1; j < data.length; ++j) {
                if (data[j].compareTo(data[minIndex]) < 0) {
                    minIndex = j;
                }
            }
            String temp = data[i];
            data[i] = data[minIndex];
            data[minIndex] = temp;
        }

       // This is how you get each gpa for each line.   
       for (int i = 0; i < data.length; i++) {
          String[] words = data[i].split(" ");
          String gpa = words[3];
          System.out.println(gpa);
       }

    }
}

其中qemu-system-i386 -hda main.img -S -s & gdb -ex 'target remote localhost:1234' \ -ex 'set architecture i8086' \ -ex 'break *0x7c00' \ -ex 'continue' boot sector

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

另见:

答案 1 :(得分:3)

正如Jester在评论中所说,您无法使用gdb运行目标文件。

并且您无法使用gdb运行16位可执行文件或16位汇编代码。您必须使用qemu之类的东西在模拟cpu上运行代码并使用gdb连接到它,或者您可以使用dosbox来运行代码并在dos上使用调试程序。并记住使用BIOS中断是一个错误是现代操作系统像Linux,因为在启动时这些操作系统禁用BIOS中断。