在 16 位汇编中写入图形像素
Write graphics pixels in 16-bit assembly
我正在尝试开发我自己的用于教育目的的非常基本的操作系统。在编写内核代码时,我试图为屏幕上的某些像素设置颜色以使其看起来更好,但我失败了。
我使用 INT 10h
和 AH = 0CH
以及视频模式 13h
(320x200 图形,256 色,1 页)并尝试了其他几种模式,例如 01h
和 03h
但它们不起作用。
这是我的完整代码:
;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
我正在尝试开发我自己的用于教育目的的非常基本的操作系统。在编写内核代码时,我试图为屏幕上的某些像素设置颜色以使其看起来更好,但我失败了。
我使用 INT 10h
和 AH = 0CH
以及视频模式 13h
(320x200 图形,256 色,1 页)并尝试了其他几种模式,例如 01h
和 03h
但它们不起作用。
这是我的完整代码:
;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