在图形模式13h中随机获得的文本无法刷新

时间:2017-07-21 22:14:56

标签: assembly x86-16 qemu bootloader

我在汇编中编写游戏,今天我注意到奇怪的问题,在0x13图形模式下屏幕底部显示的文字有时不会刷新。经过一段时间的搜索,我设法在一个更短的程序中重现问题,这只是连续不断 打印彩色数字。

我的代码:

[org 0x7c00]
[bits 16]

;Stack setup
mov bp, 0xffff
mov sp, bp

;Switch into mode 13h
mov ah, 0x00
mov al, 0x13
int 0x10

drawloop:
    ;Set cursor position
    mov ah, 2
    mov bh, 0
    mov dh, 24
    mov dl, 1
    int 0x10

    ;Load counter into al
    ;Change color to cnt value
    ;Print at page 0
    mov al, [cnt]
    mov bl, al
    mov bh, 0

    ;Print hex value of cnt (low byte)
    call puthexb

    ;Wait 1/18.2 s
    mov ax, 0
    int 0x1a
    mov bx, dx
    delay:
        int 0x1a
        cmp bx, dx
        je delay

    ;Increment counter
    inc word [cnt]

    ;Issue doesn't happen if screen isn't cleared
    call gfxcls
    jmp drawloop

jmp $

cnt: dw 0

;Clear screen
gfxcls:
    pushf
    pusha
    push es
    mov ax, 0xA000  ;Make es point video memory
    mov es, ax  ;
    mov cx, 32000   ;We will write 32000 times (word each time)
    mov di, 0   ;Start at the beginning of the vmem
    mov ax, 0   ;Fill it with 0s
    cld     ;Clear direction flag
    rep stosw   ;Kinda memset
    pop es
    popa
    popf
    ret

;Print contents of al register on screen (as hex number)
;al - value
puthexb:
    pushf
    pusha
    push ax
    and ax, 0x00f0      ;Fetch older 4 bits
    shr ax, 4       ;Shift them into lower position
    mov si, puthexb_assoc   ;
    add si, ax      ;Add offset to assoc table address
    mov al, [si]        ;Print character
    mov ah, 0xe     ;
    int 0x10        ;
    pop ax          ;Restore initial value to display
    and ax, 0x000f      ;Get 4 younger bits
    mov si, puthexb_assoc   ;
    add si, ax      ;Add offset to assoc table address
    mov al, [si]        ;Print character
    mov ah, 0xe     ;
    int 0x10        ;
    popa
    popf
    ret
    puthexb_assoc: db '0123456789abcdef'

times 510 - ( $ - $$ ) db 0
dw 0xaa55

我用这个命令组装并运行代码:

nasm -f bin vgack.asm -o vgack.bin && qemu-system-i386 -boot a -fda vgack.bin

运行一段时间后,文本停止更改,但程序继续执行(您可以通过在每次循环迭代的屏幕上的某处绘制颜色像素来轻松检查) - 这很奇怪。

在后续绘制之间,当每次在同一个地方中绘制文本并且修改了屏幕的主要部分(此处 - 在我的游戏中已清除 - 填充了第二个视频缓冲区内容)时出现问题

此外,在真正的PC上还没有发生错误 - 程序现在在笔记本电脑上运行了大约一个小时。该问题仅存在于qemu中(我的版本为1:2.5+dfsg-5ubuntu10.14 - 它看起来很旧,但apt表示它是最新版本)。那么,是否有可能,我发现了一个错误?

<小时/>

更新

事实证明,整条线都按原样重绘(或根本不重绘)。当背景被清除为不同的颜色时,可能会出现这样的效果: enter image description here

0 个答案:

没有答案