【发布时间】:2019-03-20 16:28:04
【问题描述】:
我正在尝试构建我的第一个引导加载程序,它确实可以工作,但是根据 gdb 的说法,这是我不明白的一件事。
这是我用 nasm 编写的引导加载程序:
org 0x7c00
bits 16
start: jmp boot
msg db "Bootinggggg!", 0
Print:
lodsb ;loading si to al
cmp al,0 ;loop
je PrintDone
mov ah,0eh
mov bl,14 ;yellow color
int 10h
jmp Print
PrintDone:
ret
boot:
mov ah,00h
mov al,0eh
int 10h ;stepping into graphic mode
mov si,msg
call Print
cli
cld
hlt
times 510-($-$$) db 0
dw 0xAA55
我在我的 unbuntu 机器上使用 qemu 并可视化 8086 架构。在gdb中使用ni命令几次后,gdb显示程序只是将eax添加到al,无休止。我多次按下ni,它只是不断添加它。但是当我按 continue 时,它实际上可以工作,正如您所看到的那样,它会打印字符串。为什么会这样?
【问题讨论】:
-
这里发生的事情很可能是当您点击
int 10h指令时,GDB(不是 QEMU)会感到困惑。 GDB 没有实模式段和偏移寻址的概念。当它反汇编指令时,它使用 EIP 寄存器来确定在内存中的哪个位置显示指令。它忽略了这样一个事实,即当Int 10h发生时 CS 变为非零值并开始在内存中显示 QEMU 实际上不是的指令执行。默认情况下,GDB 调试不能很好地调试实模式代码。 -
如果您想以最少的麻烦调试引导加载程序,请使用 BOCH。它理解实模式段:偏移寻址,并且对这样的代码做得很好。
-
实际上那些添加 %al, (%eax) (反汇编内存全为零的结果)是 GDB 认为 QEMU 正在执行的指令,而 QEMU 实际上正在执行正确的代码。在
int 10h完成并达到其IRET 控制后,将返回到您的引导加载程序,GDB 应在其中再次开始显示正确的指令。 -
@MichaelPetch 您应该将其添加为答案
标签: assembly gdb nasm x86-16 bootloader