在 16 位汇编中写入图形像素

Write graphics pixels in 16-bit assembly

我正在尝试开发我自己的用于教育目的的非常基本的操作系统。在编写内核代码时,我试图为屏幕上的某些像素设置颜色以使其看起来更好,但我失败了。

我使用 INT 10hAH = 0CH 以及视频模式 13h(320x200 图形,256 色,1 页)并尝试了其他几种模式,例如 01h03h 但它们不起作用。

这是我的完整代码:

;set video mode
mov ah, 00h
mov al, 13h

int 10h

;write pixels on screen
mov ah, 0ch
mov bh, 0
mov dx, 5
mov cx, 5
mov al, 0100b

int 10h

我的代码有什么问题?

编辑: 你的代码在 DOS 中工作(在我的 linux 机器上的 dosbox 中测试)。

所以它要么没有达到(您的启动过程和代码前面的代码有问题),要么您的 kernel/environment 设置阻止了 int 10h BIOS 中断工作(你不会不小心破坏 IVT 吗?)。或者您的引导加载程序已经超过 510B 大小,所以引导扇区看起来不像您期望的那样?

根据这个 wiki about Bootloaders 看起来当你将你自己的代码(或这个例子)放入磁盘的第一个扇区,并在扇区末尾用 0xAA55 标记时,它应该可以工作(而且它会最后按一下键可能会崩溃)。

您可能还想尝试他们的引导加载程序示例(编写 hello world)。


要测试直接写入 VRAM,您可以使用这样的代码(在我的 linux 机器上的 dosbox 中工作,所以如果您的 OS 设置类似的 16b 环境并允许 BIOS中断):

palette.asm:

; to compile DOS COM file: nasm -o palette.com palette.asm
; to run it with dosbox: dosbox palette.com -exit
    BITS    16
    ORG     100h
start:
    mov ax,13h
    int 10h
  ; draw palette in 32x8 squares, each square 5x5 pixels big (so 160x40px)
    push 0a000h
    pop es
    xor di,di
    xor ax,ax  ; color
    mov cx,8   ; big rows (each having 32 5x5 squares)
bigRowLoop:
    mov bx,5 ; pixel height of single row
rowLoop:
    mov dx,32 ; squares per row
    push ax
    push di
squareLoop:
    ; draw 5 pixels with "ah:al" color, ++color, di += 5
    mov [es:di],ax
    mov [es:di+2],ax
    mov [es:di+4],al
    add ax,0101h
    add di,5
    dec dx
    jnz squareLoop
    pop di
    pop ax     ; restore color for first square
    add di,320 ; move di to start of next line
    dec bx     ; do next single pixel line
    jnz rowLoop
    ; one row of color squares is drawn, now next 32 colors
    add ax,02020h ; color += 32
    dec cx
    jnz bigRowLoop
  ; wait for any key and exit
    xor ah,ah
    int 16h
    ret

以下代码以红色显示一个像素。颜色,nr,4 即。你必须用 NASM 编译它,然后它才能工作。

mov ax,13h        
int 10h             
mov ax,0A000h        
mov es,ax             
mov ax,32010          
mov di,ax             
mov dl,4             
mov [es:di],dx        
int 10h