assembly - 在 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:在此处输入图像描述
谢谢大家的支持!
解决方案
与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 0
(512而不是510)是错误的,因为它强制强制签名字节超出 512 字节引导扇区。我不明白为什么您的模拟器甚至在没有有效签名的情况下启动此代码!
jmp $
没错,但首选方法是使用cli
hlt
jmp $-2
.
推荐阅读
- java - 在Java中循环使用列表的有效方法
- python - Python - 从不同的类调用函数以使用 PyQt 画线错误:“'sip.wrappertype'”
- node.js - 如何读取当前字符串化为“对象承诺”的 JSON 对象
- python - 从python中的dict列表中查找特定值
- reactjs - 如何挂载组件 redux antd jest
- keras - yolov3.cfg 中的 batch 参数和 keras.fit() 中的 batch_size 参数有什么区别?
- javascript - 如何使用单选检查使 div 出现和消失?
- android - java.lang.RuntimeException:非法元数据值:子服务不存在
- arrays - 更新 MongoDB 中数组的特定索引
- dart - 我应该输入类型吗?