首页 > 解决方案 > 在 BIOS 中一次打印两个字符时出错

问题描述

我在 NASM 中编程时遇到问题。我正在学习如何纯粹以汇编方式开发操作系统,并从创建引导加载程序开始。

当我尝试使用print.asm文件中的打印功能时,我遇到了一次打印两个字符的错误。

文件:bootloader.asm

[BITS 16]
[ORG 0x7c00]

mov al, 65
call print_char

%include "print.asm"

jmp $

times 512-($-$$) db 0

dw 0xaa55

文件:print.asm

print_char:
mov ah, 0x0e
mov bh, 0x00
mov bl, 0x07
int 0x10
ret

qemu:在此处输入图像描述

谢谢大家的支持!

标签: assemblynasmx86-16qemuosdev

解决方案


include高级语言不同(编译器决定外部内容的去向),这%include会将print.asm文件的内容插入到您编写该行的位置。那么真正的源代码就变成了:

[BITS 16]
[ORG 0x7c00]

mov al, 65
call print_char

print_char:
mov ah, 0x0e
mov bh, 0x00
mov bl, 0x07
int 0x10
ret

jmp $

times 512-($-$$) db 0

dw 0xaa55

如您所见,一旦call print_char返回,代码就会进入print_char例程,从而第二次执行相同的指令(产生“AA”)。
此外,由于第二次ret指令在堆栈上没有合理的返回地址,计算机将崩溃,但以一种危险的方式,因为不知道执行将去哪里!
如果你愿意,这jmp $也是一个崩溃,但至少它是一个“安全”的。

这就是您的代码应该是的:

[BITS 16]
[ORG 0x7C00]

mov al, 65
call print_char

cli
hlt
jmp $-2

%include "print.asm"

times 510-($-$$) db 0
dw 0xAA55

times 512-($-$$) db 0512而不是510)是错误的,因为它强制强制签名字节超出 512 字节引导扇区。我不明白为什么您的模拟器甚至在没有有效签名的情况下启动此代码!
jmp $没错,但首选方法是使用cli hlt jmp $-2.


推荐阅读