想做的是停在BIOS第一条指令处并查看一些寄存器的信息,为此进行了以下操作:
在Makefile中加入以下代码:
lab1-mon: $(UCOREIMG) $(V)$(TERMINAL) -e "$(QEMU) -S -s -d in_asm -D $(BINDIR)/q.log -monitor stdio -hda $< -serial null" $(V)sleep 2 $(V)$(TERMINAL) -e "gdb -q -x tools/lab1init"
其中的-monitor stdio -hda参数会启动qemu的monitor,可以在其中显示一些信息;
在tools/lab1init文件中加入以下初始化gdb的代码:
file bin/kernel
set architecture i386
target remote :1234
这时运行
make lab1-mon
应当会启动一个qemu、一个qemu的monitor、一个gdb的命令行,并且停在执行第一条指令之前。
这时如果查看当前pc及之后的汇编代码,在gdb命令行和monitor中分别运行
x /10i $pc
会发现结果不一样,理论上这时$pc应是0xfffffff0,gdb显示的却是0x0000fff0:
(gdb) x /10i $pc => 0xfff0: add %al,(%eax) 0xfff2: add %al,(%eax) 0xfff4: add %al,(%eax) 0xfff6: add %al,(%eax) 0xfff8: add %al,(%eax) 0xfffa: add %al,(%eax) 0xfffc: add %al,(%eax) 0xfffe: add %al,(%eax) 0x10000: add %al,(%eax) 0x10002: add %al,(%eax)
monitor显示是正确的预期结果:
(qemu) x /10i $pc 0xfffffff0: ljmp $0xf000,$0xe05b 0xfffffff5: xor %dh,0x322f 0xfffffff9: xor (%bx),%bp 0xfffffffb: cmp %di,(%bx,%di) 0xfffffffd: add %bh,%ah 0xffffffff: add %al,(%bx,%si) 0x00000001: add %al,(%bx,%si) 0x00000003: add %al,(%bx,%si) 0x00000005: add %al,(%bx,%si) 0x00000007: add %al,(%bx,%si)
实际测试中还发现如果在gdb中设置断点为32位的地址处,比如0xfe05b,gdb会显示停到了低16位的地址处0xe05b,并且继续用si单步执行的话也执行不下去。所以猜测gdb对于32位的内存地址设置断点还有显示会有一些问题?这样的话对于之后在gdb中调试可能会产生一些影响,是否可能需要在gdb中进行某些设置或者是其他什么原因?