x86 BIOS引导程序开发:如何获取屏幕像素尺寸以绘制全屏矩形
实现方案与代码修正
你当前的代码存在两个核心问题:
- 你设置的
13hVGA模式是固定320x200分辨率的,硬编码SI=1920、DI=1080完全超出该模式的寻址范围,无法绘制出正确的全屏矩形 - 开头无参数的
int 0x15是无效调用,无法获取任何屏幕参数
1. 分辨率获取方法
你可以通过BIOS int 10h的0xF子功能获取当前显示模式的像素尺寸,逻辑如下:
- 调用
mov ah, 0xF+int 10h,返回的AH寄存器存储每行字符数,乘以VGA默认的8像素/字符,即可得到屏幕宽度 - 调用
int 10h的0x1130子功能获取字符高度,乘以25行(VGA默认文本行数)得到屏幕高度;如果是图形模式也可以直接使用对应模式的固定高度,或者用VBE功能获取更精准的参数
如果你需要使用1920x1080这类高分辨率,需要先切换到VESA(VBE)显示模式,再调用VBE的0x4F01子功能读取指定模式的分辨率参数存入SI、DI即可。
2. 修正后的完整代码
bits 16 org 100h start: ; 切换到13h 320x200 256色图形模式 mov ah, 0 mov al, 13h int 10h ; 获取当前显示模式参数 mov ah, 0xF int 10h ; 计算屏幕宽度:每行字符数 * 8像素/字符,存入SI mov bl, 8 mul bl mov si, ax ; 13h模式固定高度200,存入DI,也可以通过VBE功能动态获取 mov di, 200 ; 绘制全屏矩形,颜色为0x1(蓝色) mov cx, 0 mov dx, 0 mov al, 0x1 call draw_box ; 停机 jmp $ draw_box: push si push cx .xdraw: push di push dx .ydraw: pusha mov bh, 0 ; 当前cx为x坐标,dx为y坐标,直接写入像素 mov ah, 0xC int 0x10 popa inc dx sub di, 1 jnz .ydraw pop dx pop di inc cx sub si, 1 jnz .xdraw pop cx pop si ret
3. 代码改动说明
- 移除了无效的
int 0x15调用,新增分辨率获取逻辑,自动计算当前模式的宽高存入SI、DI,不需要硬编码参数 - 修复了原
draw_box的坐标计算错误,原逻辑中add cx,si、add dx,di会导致坐标超出屏幕范围,改为逐像素遍历的逻辑 - 增加了停机指令避免代码跑飞
内容的提问来源于stack exchange,提问作者804k
相关产品推荐
相关产品推荐

