如果这个问题看起来有点愚蠢,我提前道歉......
我目前正在开发一个简单的 16 位实模式操作系统,使用 x86 程序集(NASM)和 Ubuntu Mate Linux 16.04.3 LTS 作为我的开发平台和用于调试系统的 Virtualbox。到目前为止编写的引导加载程序和底层内核代码工作正常,但是我似乎遇到了我正在编写的图形代码的一些问题。我已经通过 INT10h 切换到 640x480x256 分辨率的 SVGA:
Services.screen_textmode.enter_svga:
pusha
mov ax, 4F02h
mov bx, 101h
int 10h
popa
ret
然后将控制权转移回内核,该内核将像素的颜色保存在 dl 寄存器中的下一个函数(我遇到问题的那个)并调用该函数:
mov dl, 2
call Services.svga.draw_background
现在我遇到的问题是,当运行以下代码时,每次切换视频内存库时,它似乎都会掩盖 dl 寄存器所持有的字节,并且会改变每个库的颜色,或者整个屏幕是纯黑色。这是代码:
Services.svga.draw_background:
pusha
xor cx, cx
xor dx, dx
mov word [svga_bank], dx
mov ax, 0A000h
mov es, ax
.start_bank:
mov di, cx
mov [es:di], dl
.finish_bank:
inc cx
mov di, cx
mov [es:di], dl
cmp cx, 65535
je .switch_bank
jmp .finish_bank
.switch_bank:
xor cx, cx
mov word dx, [svga_bank]
inc dx
mov word [svga_bank], dx
push ax
push bx
mov ax, 4F05h
xor bx, bx
int 10h
pop ax
pop bx
cmp dx, 5
je .done
jmp .start_bank
.done:
popa
ret
我为什么要在 Services.svga.draw_background 函数运行之前设置 dl 背后的想法是,操作系统最终将能够加载配置文件,这些配置文件将为应用程序和菜单设置配色方案,从而使系统更具可定制性。
我已经尝试了一切:我找到了银行切换的不同方法,直接在 .start_bank 中设置 dl 等。没有任何效果,经过详尽的研究后我找不到任何东西。显然,如果我在银行切换期间不存储 dx 的值,即使存在导致系统进入无限循环的指令“inc dx”,它也永远不会改变,并且当银行切换正常工作时,改变值的行为dx 的值也以某种方式改变了 dl 的值......有谁知道如何解决这个问题?