Assembly x86汇编VGA图形是否存在NASM故障?

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

如果这个问题看起来有点愚蠢,我提前道歉

我目前正在使用x86汇编(NASM)和Ubuntu Mate Linux 16.04.3 LTS开发一个简单的16位实模式操作系统,并使用Virtualbox调试系统。到目前为止,所编写的引导加载程序和底层内核代码运行良好,但是我似乎在所编写的图形代码中遇到了一些问题。我已通过INT10h切换到640x480x256分辨率的SVGA:

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