如何在 nasm os 中填充屏幕

How to fill the screen in a nasm os

我目前正在 nasm 中制作我自己的自定义 os,我正在尝试制作一个错误屏幕。所以我需要用红色填充屏幕。到目前为止,这是我的 16 位代码。

sysError:
    mov cx, 24 ;empty lines
    .loop:
    call printNL
    loop .loop
    mov ah, 0x02 ;set cursor
    mov bh, 0x00 ;page 0
    mov dh, 0x00 ;0th row
    mov dl, 0x00 ;0th char
    mov bl, 17h
    int 0x10 ;set cursor
    pop cx
    add cx, (skip_NL-main_loop)
    push cx
    ;fill with red here
    mov si, errorSTR
    call printString
    jmp hang
    hang:
        jmp hang

它清除屏幕并将错误消息打印到屏幕上。

您可以使用 Int 10h/AH=6 向上滚动 window 并有效地让 BIOS 以指定的前景色和背景色清除屏幕。一个简单的引导加载程序可以用红底白字清除屏幕:

TEXTMODE_NUM_ROWS EQU 25
TEXTMODE_NUM_COLS EQU 80

; EGA Color Palette can be found here:
;    https://en.wikipedia.org/wiki/Enhanced_Graphics_Adapter#Color_palette
COLOR_RED          EQU 4
COLOR_BRIGHT_WHITE EQU 15

org 0x7c00

main:    
    xor ax, ax                 ; DS=ES=0x0000
    mov ds, ax
    mov es, ax
    mov ss, ax                 ; SS:SP = 0x0000:0x7c00 (grow down beneath bootloader)
    mov sp, 0x7c00
    cld                        ; DF=0 forward string instruction movement

    ; http://www.ctyme.com/intr/rb-0096.htm
    ; Int 0x10
    ; AH = 06h
    ; AL = number of lines by which to scroll up (00h = clear entire window)
    ; BH = attribute used to write blank lines at bottom of window
    ; CH,CL = row,column of window's upper left corner
    ; DH,DL = row,column of window's lower right corner    
    mov ax, 0x0600             ; AH = 6 = Scroll Window Up, AL = 0 = clear window
    mov bh, COLOR_RED << 4 | COLOR_BRIGHT_WHITE
                               ; Attribute to clear screen with (White on Red)
    xor cx, cx                 ; Clear window from 0, 0
    mov dx, TEXTMODE_NUM_ROWS << 8 | TEXTMODE_NUM_COLS
                               ; Clear window to 24, 80
    int 0x10                   ; Clear the screen

    mov ah, 0x02               ; Set cursor
    mov bh, 0x00               ; Page 0
    mov dx, 0x00               ; Row = 0, Col = 0
    int 0x10

    cli
.endloop:
    hlt
    jmp .endloop

TIMES 510-($-$$) db 0x00       ; Pad Boot sector to 510 bytes
dw 0xaa55                      ; Boot signature

或者,您可以通过直接写入 0xb800:0x0000 处的文本显存,向屏幕上的每个单元格写入一个 space 字符和一个属性来清除显示。物理地址 0xb8000 是文本视频内存的第 0 页开始的地方。代码可能如下所示:

TEXTMODE_NUM_ROWS EQU 25
TEXTMODE_NUM_COLS EQU 80
TEXTMODE_VID_SEG  EQU 0xb800

; EGA Color Palette can be found here:
;    https://en.wikipedia.org/wiki/Enhanced_Graphics_Adapter#Color_palette
COLOR_RED          EQU 4
COLOR_BRIGHT_WHITE EQU 15

org 0x7c00

main:
    xor ax, ax                 ; DS = 0x000
    mov ds, ax
    mov ss, ax                 ; SS:SP = 0x0000:0x7c00 (grow down beneath bootloader)
    mov sp, 0x7c00
    cld                        ; DF=0 forward movement

    mov bx, TEXTMODE_VID_SEG
    mov es, bx                 ; ES = Text video memory segment
    xor di, di                 ; DI = 0x0000 offset to upper left of display (page 0)
    mov ax, (COLOR_RED << 4 | COLOR_BRIGHT_WHITE) << 8 | ' '
                               ; Attribute to clear screen with (White on Red)
                               ; Clear with ' ' space character
    mov cx, TEXTMODE_NUM_ROWS * TEXTMODE_NUM_COLS
                               ; CX = number of screen cells (words) to clear
    rep stosw                  ; Clear the display a word at a time

    mov ah, 0x02               ; Set cursor
    mov bh, 0x00               ; Page 0
    mov dx, 0x00               ; Row = 0, Col = 0
    int 0x10

    cli
.endloop:
    hlt
    jmp .endloop

TIMES 510-($-$$) db 0x00       ; Pad Boot sector to 510 bytes
dw 0xaa55                      ; Boot signature