【问题标题】:Cannot draw pixels on Y-axis with INT 10h / AH = 0ChINT 10h / AH = 0Ch 无法在 Y 轴上绘制像素
【发布时间】:2016-01-01 03:50:50
【问题描述】:

我有以下代码片段,它应该从 (30, 100) 开始绘制对角线,但是,它只是在屏幕顶部绘制一条水平线,如下所示:

为了测试代码,我运行make run

这是loader.asm

    BITS 16

; ----------------------------------------------------------------------

_start:
    mov ax, 07C0h
    add ax, 288
    mov ss, ax              ; ss = stack space
    mov sp, 4096            ; sp = stack pointer

    mov ax, 07C0h
    mov ds, ax              ; ds = data segment

    call print_pixel

    jmp $                   ; infinite loop

; ----------------------------------------------------------------------

print_pixel:

    ; changing video mode to graphical

    mov ah, 00h             ; set video mode

    mov al, 13h             ; 13h - graphical mode.
                            ; 40x25. 256 colors.;320x200 pixels. 1 page.

    int 10h                 ; call

    ; drawing random pixels

    mov ah, 0Ch             ; change color for a single pixel

    mov al, 0000b           ; color
    mov bh, 0               ; page number
    mov cx, 30              ; x
    mov dx, 100             ; y

    int 10h                 ; paint 1st pixel

.repeat:

    inc al                  ; change color
    inc cx                  ; go one pixel right
    inc dx                  ; go one pixel down

    int 10h                 ; paint

    cmp al, 1111b
    je .done                ; last color was painted

    jmp .repeat

.done:
    ret

times 510 - ($ - $$) db 0   ; padding with 0 at the end
dw 0xAA55                   ; PC boot signature

这是Makefile

.PHONY: build run

build: image.flp

run: build
    qemu-system-i386 -fda image.flp

image.bin: loader.asm
    nasm -f bin -o image.bin loader.asm

image.flp: image.bin
    dd status=noxfer conv=notrunc if=image.bin of=image.flp

【问题讨论】:

  • 无法再现水平线。对我来说很好。
  • @cad 你在使用我的 Makefile 和make run吗?
  • 是的,一样。它在 ArchLinux、Linux 4.1.6、64 位上。
  • 也许你应该在另一个模拟器上测试它,比如 bochs。
  • @cad 我正在运行 Ubuntu 15.04、Linux 3.19、64 位。我会尝试bochs,但设置起来似乎更困难,而且我没有找到任何让它运行的指南。我想继续使用qemu。我相信使用另一个 -display 可能会解决我的问题,但似乎最好的选择 -display gtk 已被禁用。

标签: assembly graphics nasm x86-16 bootloader


【解决方案1】:

您似乎偶然发现了 QEMU 在我们的 Ubuntu 版本上使用的默认 Plex86 VGA BIOS 的错误。它可能是 Plex86 VGA 代码中的错误; SeaBIOS 和 Plex86 之间的错误; Ubuntu/Debian 团队用于构建该 BIOS 的选项可能存在一些问题。您或许可以尝试使用 Cirrus VGA BIOS,方法是修改您的 Makefile,以便此行:

qemu-system-i386 -fda image.flp

改为:

qemu-system-i386 -fda image.flp -vga cirrus

我碰巧在 Ubuntu 15.04 上运行了您的代码并且有类似的行为。 DX 寄存器的内容似乎没有被接受(其中包含 Y 轴值)。

虽然在这种情况下不是您的问题的一部分 - 在使用 int 10h 时,您不应该假设 AX/AH/AL注册将被保留。有一些较旧的 VGA BIOS 可能会破坏它。

我还在我的 Debian Jessie 系统上发现您的代码最初可以运行,如果我通过运行以下命令专门使用 Plex86 VGA BIOS,它会失败:

qemu-system-i386 -fda image.flp -vga std

看来此问题并非特定于 Ubuntu。它也会影响 Debian。似乎 Debian 可能在未指定时默认使用不同的 VGA BIOS。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多