Assembly x86汇编VGA图形是否存在NASM故障?
如果这个问题看起来有点愚蠢,我提前道歉 我目前正在使用x86汇编(NASM)和Ubuntu Mate Linux 16.04.3 LTS开发一个简单的16位实模式操作系统,并使用Virtualbox调试系统。到目前为止,所编写的引导加载程序和底层内核代码运行良好,但是我似乎在所编写的图形代码中遇到了一些问题。我已通过INT10h切换到640x480x256分辨率的SVGA:Assembly x86汇编VGA图形是否存在NASM故障?,assembly,x86,operating-system,nasm,vesa,Assembly,X86,Operating System,Nasm,Vesa,如果这个问题看起来有点愚蠢,我提前道歉 我目前正在使用x86汇编(NASM)和Ubuntu Mate Linux 16.04.3 LTS开发一个简单的16位实模式操作系统,并使用Virtualbox调试系统。到目前为止,所编写的引导加载程序和底层内核代码运行良好,但是我似乎在所编写的图形代码中遇到了一些问题。我已通过INT10h切换到640x480x256分辨率的SVGA: Services.screen_textmode.enter_svga: pusha mov ax, 4
Services.screen_textmode.enter_svga:
pusha
mov ax, 4F02h
mov bx, 101h
int 10h
popa
ret
控件然后将get传输回内核,内核将保存像素的颜色以用于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_后台函数运行之前设置dl?背后的想法是,操作系统最终将能够加载配置文件,为应用程序和菜单设置颜色方案,从而使系统更加可定制
我尝试了所有的方法:我找到了不同的银行转换方法,直接将dl设置为in.start_bank,等等。没有任何效果,经过详尽的研究,我找不到任何东西。显然,如果我在银行切换期间不存储dx的值,即使存在“inc dx”指令,它也不会更改,这会导致系统进入无限循环,并且当银行切换正常工作时,更改dx值的行为也会以某种方式更改dl的值。。。有人知道如何解决这个问题吗?因为
DL
已经是DX
的一部分,您不能同时使用DL
保存颜色和DX
保存银行号码。这是
您的努力也失败了,因为Services.svga.draw_后台例程中还有一个问题
此代码段无法正确还原寄存器!pop
的顺序必须与推送的顺序相反
push ax
push bx
...
pop bx
pop ax
在这个svga_bank变量中移动零并开始写入第一个bank是不够的。物理银行选择可以指向任何其他银行。e、 g.在本Services.svga.draw_后台例程结束时,实际银行为5,银行编号甚至无效(此处的有效范围为[0,4])
我写这封信是为了方便你。我把颜色放在了CL
中
Services.svga.draw_background:
pusha
push ds
mov ax, 0A000h
mov ds, ax ; DS:DI is start of video
xor di, di
mov ch, cl ; CL holds the color [0,255]
xor dx, dx ; Initial bank
.again:
mov ax, 4F05h ; VESA.SelectBank 0, 1, 2, 3
xor bx, bx
int 10h
.color:
mov [di], cx
add di, 2
jnz .color
inc dx
cmp dx, 4
jb .again
mov ax, 4F05h ; VESA.SelectBank 4
xor bx, bx
int 10h
.LastBank:
mov [di], cx
add di, 2
cmp di, 45056
jb .LastBank
pop ds
mov word [svga_bank], dx
popa
ret
640x480的分辨率为307200字节。这是65536字节的4倍,剩余的45056字节
提示
您可以通过编写DWORD(ECX
)而不是单词(CX
)来加快速度 “改变dx的值也会改变dl的值”-你知道dl
是dx
的低位8位,对吧?不,我没有。我再次道歉。。。如果你不知道的话,我仍然是asm的不速之客。冒着听起来更不自然的风险,似乎如果我从使用dl切换到bl,屏幕上的颜色就会相同,就在其他每一个银行(银行0:我要找的颜色,银行2:黑色,银行3:我的颜色,等等)。我将不得不做一些更多的测试,但感谢您向我指出这一点。可能重复(如果这一误解是您的主要错误):显示AX分解为AH:AL,BX、CX、DX也是如此。
xor dx, dx
mov word [svga_bank], dx
Services.svga.draw_background:
pusha
push ds
mov ax, 0A000h
mov ds, ax ; DS:DI is start of video
xor di, di
mov ch, cl ; CL holds the color [0,255]
xor dx, dx ; Initial bank
.again:
mov ax, 4F05h ; VESA.SelectBank 0, 1, 2, 3
xor bx, bx
int 10h
.color:
mov [di], cx
add di, 2
jnz .color
inc dx
cmp dx, 4
jb .again
mov ax, 4F05h ; VESA.SelectBank 4
xor bx, bx
int 10h
.LastBank:
mov [di], cx
add di, 2
cmp di, 45056
jb .LastBank
pop ds
mov word [svga_bank], dx
popa
ret