You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OS开发:在Netwide Assembler(NASM)中获取图形模式屏幕分辨率

获取实模式图形模式下的屏幕分辨率与逐行填充实现

一、获取屏幕分辨率的方法

1. 传统VGA固定模式(如0x13模式)

如果使用标准VGA图形模式(比如320×200 256色的模式0x13),这类模式的分辨率是固定的,可直接硬编码。若需动态确认,可通过BIOS中断获取当前模式信息:

  • 调用int 0x10,功能号AH=0x0F:
    • 返回AH为当前视频模式编号
    • 根据模式编号查表即可得到对应分辨率(比如模式0x13对应320×200)

2. VBE扩展模式(支持高分辨率)

若需使用更高分辨率的图形模式(如640×480、800×600等),需借助VESA BIOS Extensions (VBE) 获取参数:

  • 先调用int 0x10,AX=0x4F00,获取VBE控制器信息,其中包含支持的模式列表
  • 再调用int 0x10,AX=0x4F01,传入目标模式编号,获取该模式的详细参数(含宽度、高度、位深等)

以下是获取当前VBE模式分辨率的NASM代码片段:

; 定义VBE模式信息结构体
struc VbeModeInfo
    .ModeAttr       resw 1
    .WinAAtttr      resb 1
    .WinBAttr       resb 1
    .WinGranularity resw 1
    .WinSize        resw 1
    .WinASegment    resw 1
    .WinBSegment    resw 1
    .WinFuncPtr     resd 1
    .BytesPerScanLine resw 1
    .XResolution    resw 1
    .YResolution    resw 1
    .XCharSize      resb 1
    .YCharSize      resb 1
    .NumberOfPlanes resb 1
    .BitsPerPixel   resb 1
    .NumberOfBanks  resb 1
    .MemoryModel    resb 1
    .BankSize       resb 1
    .NumberOfImagePages resb 1
    .Reserved0      resb 1
    .RedMaskSize    resb 1
    .RedFieldPos    resb 1
    .GreenMaskSize  resb 1
    .GreenFieldPos  resb 1
    .BlueMaskSize   resb 1
    .BlueFieldPos   resb 1
    .RsvdMaskSize   resb 1
    .RsvdFieldPos   resb 1
    .DirectColorModeInfo resb 1
    .PhysBasePtr    resd 1
    .Reserved1      resd 1
    .Reserved2      resw 1
    .Reserved3      resb 1
    .LinearBytesPerScanLine resw 1
    .BanksPerImage  resb 1
    .Reserved4      resb 3
    .Reserved5      resd 1
    .Reserved6      resd 1
    .Reserved7      resb 16
endstruc

; 获取当前VBE模式的分辨率
get_vbe_resolution:
    pusha
    mov ax, 0x4F01       ; VBE功能:获取模式信息
    mov cx, 0x101        ; 示例模式:640×480 256色,可替换为实际使用的模式号
    mov di, vbe_mode_info
    int 0x10
    ; 检查返回值,AH=0表示调用成功
    cmp ah, 0
    jne .error

    ; 分辨率存储在vbe_mode_info.XResolution(宽度)和.YResolution(高度)中
    mov ax, [vbe_mode_info + VbeModeInfo.XResolution]
    mov bx, [vbe_mode_info + VbeModeInfo.YResolution]
    ; 此处可将AX、BX的值保存到内存或寄存器供后续使用
    jmp .done
.error:
    ; 调用失败时的 fallback 处理,比如切换到传统VGA模式
.done:
    popa
    ret

section .bss
vbe_mode_info resb VbeModeInfo_size

二、逐行填充屏幕的实现

以传统VGA模式0x13(320×200 256色)为例,显示内存起始地址为0xA0000,每个字节对应一个像素的颜色值。逐行填充只需按行遍历显示内存,每行写入对应数量的像素值:

; 设置VGA图形模式0x13
set_video_mode:
    mov ah, 0x00
    mov al, 0x13
    int 0x10
    ret

; 逐行填充屏幕,颜色值存于BL中
fill_screen_rowwise:
    pusha
    mov ax, 0xA000
    mov es, ax           ; ES指向显示内存段
    xor di, di           ; DI初始化为0,指向显示内存起始位置
    mov cx, 200          ; 总行数(Y分辨率)
.fill_row:
    mov dx, 320          ; 每行像素数(X分辨率)
    mov al, bl           ; 要填充的颜色值
    rep stosb            ; 填充一行320个像素
    loop .fill_row       ; 处理下一行
    popa
    ret

; 主引导扇区代码
section .text
org 0x7C00
start:
    call set_video_mode
    mov bl, 0x0F         ; 256色模式下的白色值
    call fill_screen_rowwise
    jmp $                ; 无限循环

; 填充引导扇区到512字节
times 510 - ($ - $$) db 0
dw 0xAA55

如果使用VBE线性帧缓冲模式,只需将显示内存地址替换为vbe_mode_info.PhysBasePtr,再根据XResolution、YResolution和位深计算每行字节数(比如24位色每行字节数=宽度×3),即可按相同逻辑逐行填充。

注意事项

  • Bochs默认支持VBE,可在配置文件中添加vga: extension=vbe确保功能正常
  • 不同图形模式的显示内存布局不同,需根据模式参数调整填充逻辑
  • 实模式下内存寻址限制为1MB,高分辨率模式可能需要使用分页或段切换(若显示内存超过1MB)

内容的提问来源于stack exchange,提问作者user1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 15:01:04