当前文本模式页的地址记录在何处?如何直接获取当前工作视频缓冲区地址
实模式文本模式下查询当前工作视频缓冲区的方法
你提到的mov ah, 15搭配int 10h的中断调用,确实是BIOS提供的标准接口,执行后会把当前激活的文本页号存入bh寄存器,这个接口的返回值本身不直接包含页地址信息。
可直接使用的固定内存存储位置
在实模式下的BIOS数据区(对应物理地址起始00400000,实模式段地址0040h),有几个固定偏移的存储位,可以直接读取获取视频缓冲区相关的基础参数,不需要自行做硬件类型判断:
- 偏移0049h:存储当前激活的视频模式值,可直接区分当前是单色文本页帧(对应基地址B0000h)还是彩色文本页帧(对应基地址B8000h)
- 偏移004Eh:存储当前使用的CRTC控制器的基端口地址,值为3B4对应单色适配器,3D4对应彩色适配器
这里需要明确:没有专门的固定内存位置直接存储“当前工作页相对于页帧基地址的偏移值”,BIOS内部维护的页映射关系属于中断处理的内部参数,没有对外暴露成可直接读取的常量。
可直接读取硬件信息的端口方案
如果不需要做手动计算、也不需要预先存储所有页的地址常量,可以直接通过CRTC硬件端口读取当前实际使用的视频缓冲区起始位置,这个是硬件层面锁存的实时值,完全不受BIOS换算规则的影响:
- 核心逻辑:CRTC控制器本身的寄存器会实时记录“屏幕左上角对应的显存偏移地址”,不管这个偏移是BIOS通过中断设置的,还是程序直接修改硬件寄存器设置的,读出来的就是当前正在往屏幕输出的缓冲区起点
- 读取步骤:
- 从之前提到的BIOS数据区拿到CRTC的基端口值
- 向CRTC索引端口(也就是基端口本身)写入寄存器索引
0Ch,从相邻的数据端口(基端口+1)读出16位偏移的高8位 - 再向索引端口写入寄存器索引
0Dh,从数据端口读出16位偏移的低8位 - 把两个字节拼接成16位值,就是当前工作视频缓冲区相对于页帧基地址的实际偏移
- 方案优势:哪怕你使用的是非标准文本模式(比如自定义的行列数、自定义的单页长度),不需要自己记忆换算规则,也能拿到准确的当前缓冲区位置,完全符合你不想手动计算、不想预存所有页地址的需求。
补充说明:这个硬件读到的偏移值,和BIOS返回的当前页号是强对应的,但相比手动通过页号乘以单页长度算出来的结果,在做过自定义显存窗口调整、非标准模式的场景下准确度更高。
内容的提问来源于stack exchange,提问作者Ahmed Crow
相关产品推荐
相关产品推荐

