【问题标题】:Boot loader keeps adding eax to al引导加载程序不断将 eax 添加到 al
【发布时间】: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


【解决方案1】:

您正在拆卸空白内存。 00 00add %al, (%eax)add [eax], al 的编码。您可以使用this online disassembler 轻松检查

0:  00 00                   add    BYTE PTR [eax],al

请注意,该指令不是将 eax 添加到 al。它将 al 添加到 eax 指向的地址处的值

【讨论】:

  • 那为什么它只在我输入“继续”后才播放黄色字符串,而不是在相应的汇编命令后播放?
  • 大概控制以某种方式脱离了hlt,例如由于调试器使用int3。要进行无限循环,最好将jmp 放回hlt
  • @jester 避免死循环不是更好吗?我应该把“jmp”放在哪里?
  • l: hlt; jmp l
  • 在这种情况下,GDB 显示的是 QEMU 并未实际执行的指令。因为 GDB 在实模式下没有段的概念:偏移地址 - 当int 10h 完成时,CS 和 IP 被修改为开始在 BIOS 内存中执行(可能在物理地址 0xF0000 以上)。 GDB 只是使用 IP(EIP) 的值来反汇编指令,而忽略了 CS 中的值。当然在实模式下 CS:IP 用公式 (segment
猜你喜欢
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
  • 2021-10-23
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多