我正在使用一个简单的程序集片段,使用 BIOS 作为引导加载程序的一部分将字符打印到屏幕上。这是引导加载程序代码。
[org 0x7c00]
[bits 16]
%include "a20_check.asm"
mov ah, 0x0e
mov al, 'H'
int 0x10
times 510 - ($-$$) db 0
dw 0xaa55
这是a20_check.asm函数的代码,取自osdev.org .
[bits 16]
; Returns: 0 in ax if the a20 line is disabled (memory wraps around)
; 1 in ax if the a20 line is enabled (memory does not wrap around)
check_a20:
pushf
push ds
push es
push di
push si
cli
xor ax, ax ; ax = 0
mov es, ax
not ax ; ax = 0xFFFF
mov ds, ax
mov di, 0x0500
mov si, 0x0510
mov al, byte [es:di]
push ax
mov al, byte [ds:si]
push ax
mov byte [es:di], 0x00
mov byte [ds:si], 0xFF
cmp byte [es:di], 0xFF
pop ax
mov byte [ds:si], al
pop ax
mov byte [es:di], al
mov ax, 0
je check_a20__exit
mov ax, 1
check_a20__exit:
pop si
pop di
pop es
pop ds
popf
ret
问题似乎出在最后一个标签,check_a20__exit。如果我注释掉ret
,那么该字符就会打印到屏幕上。否则,不会打印。
有人可以向我解释一下这个问题吗?
最佳答案
如果您考虑一下您自己对故障排除的描述,然后查看您如何包含代码,那么问题是什么应该是显而易见的。
- 首先,添加用于检查 A20 线的代码
- 该代码以
ret
结尾 - 接下来我们找到在屏幕上打印字符的代码
- 最后我们有了空填充
显然,ret
将尝试使用当前位于 SP
的任何内容并在那里切换执行路径...但您从未调用过任何内容,因此数据只是垃圾。
删除 ret
可以让它“穿透”到您的打印代码。
关于程序集 BIOS 调用不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45062880/