程序集 BIOS 调用不起作用

标签 assembly x86 bootloader bios x86-16

我正在使用一个简单的程序集片段,使用 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/

相关文章:

assembly - 我的操作系统无法在 VMWare 中启动

kernel - 我的操作系统内核在 D : Some embedded strings don't work

c++ - 使用 C 中系统调用的文件描述符

c++ - 在Intel x86中读取缓存行与部分缓存行

assembly - 为什么我无法转换应用程序中的架构?

c - 函数返回局部变量的地址,但仍在c中编译,为什么?

C/Assembler - 在没有堆栈的单用户、单任务操作系统中返回代码

command-line - 如何让 uBoot 与 squashfs 一起工作/uBoot 中的 FDT 是什么?

assembly - 是否有用于 16 字节宽 VTBL 的 Armv8-A 内在函数?

delphi - FPU。如何制作一个循环?