Assembly Qemu错误地重复视频电传打字机(int 0x10/ah=0xE)

Assembly Qemu错误地重复视频电传打字机(int 0x10/ah=0xE),assembly,x86-16,qemu,bootloader,bios,Assembly,X86 16,Qemu,Bootloader,Bios,我试图从中复制qemu hello单词示例。代码似乎没有太多的漏洞空间: # 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 te

我试图从中复制qemu hello单词示例。代码似乎没有太多的漏洞空间:

# 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——格式二进制文件-e init boot.o
qemu-system-x86_64 boot.bin
字符“A”被打印多次:

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

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


提前谢谢。

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

代码错误,因为
hlt
仅在下一次中断之前停止cpu。当下一个中断到达时,cpu恢复并继续运行垃圾代码(此处:0x00 0x00…0x00 0x55 0xaa 0xrandom BURGE),其中可能出现并执行
int
的机器代码,从而重复打印“A”

正如Brendan所建议的那样,停止cpu的正确方法是将
hlt
指令放入无限循环:

.die
hlt
jmp .die

在您使用hlt之前禁用中断。
hlt
指令只是等待下一个中断。启动时,中断每隔几毫秒发生一次。@fuz:最好使用无限循环(如
.die:hlt
jmp.die
)。禁用IRQ不会禁用NMI之类的东西,因此不是“100%防弹”解决方案;但它确实禁用了键盘IRQ,并阻止您使用“control+alt+delete”重新启动(这可能会让人讨厌)。谢谢您提供的信息。我已经把你的评论总结成一个答案。