assembly - Qemu 错误地重复了 Video Teletype (int 0x10/ah=0xE)

标签 assembly x86-16 qemu bootloader bios

我正在尝试重现 the post 中的 qemu hello-word 示例.代码似乎没有太多错误空间:

# boot.asm
.code16 
.global init       # makes our label "init" available to the outside 
init:              # this is the beginning of our binary later. 
  mov $0x0e41, %ax # sets AH to 0xe (function teletype) and al to 0x41 (ASCII "A") 
  int $0x10        # call the function in ah from interrupt 0x10 
  hlt              # stops executing 
.fill 510-(.-init), 1, 0 # add zeroes to make it 510 bytes long 
.word 0xaa55       # magic bytes that tell BIOS that this is bootable

但是在编译它并用 qemu 加载它之后:

as -o boot.o boot.asm
ld -o boot.bin --oformat binary -e init boot.o
qemu-system-x86_64 boot.bin

多次打印字符“A”: enter image description here

我已经多次重复这个实验。大多数情况下它表现正常并且只打印一次字符。有时它会重复该字符 2 或 3 次。屏幕截图显示了一种罕见但存在的行为。

有人知道这是怎么发生的吗?

提前致谢。

最佳答案

让我总结一下 fuz 和 Brendan 的评论。

代码错误,因为 hlt 仅在下一次中断之前停止 cpu。当下一个中断到来时,cpu 恢复并继续运行垃圾代码(这里:0x00 0x00 ... 0x00 0x55 0xaa 0xrandom-garbage),其中 int 的机器代码可能会出现并被执行,从而重复打印'A'。

按照 Brendan 的建议,停止 CPU 的正确方法是将 hlt 指令放入无限循环中:

.die
hlt
jmp .die

关于assembly - Qemu 错误地重复了 Video Teletype (int 0x10/ah=0xE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65278796/

相关文章:

assembly - 访问 PIT (?) IO 端口 44h 和 46h - 这些端口有什么作用?

solaris - 在 QEMU 上模拟 Solaris 10 SPARC

ubuntu - QEMU - 无法在访客和主机之间连接,但两者都连接到路由器

c++ - x86 Intel Assembly 和 C++ - 数组周围的堆栈已损坏

assembly - 从程序集调用 C 函数——应用程序在 "call printf"处卡住,我不知道为什么

assembly - 内存地址和偏移量

x86调用栈保存一个字节

c - 当我按下键盘上的键时如何防止重复的字符

macos - 一个好的 8086 模拟器

c - 如何使用一个终端调试 QEMU?