使用BIOS以及直接写显存绘制图形
注:以下程序系由相应的Intel格式汇编改编而来,略有修改,若发现bug,欢迎指正。若有问题,欢迎交流。若能帮助一二访客,幸甚。
一年前仿照Skelix 写过一个简单的内核,并命名为BabyOS。当时代码大部分用的Skelix的,终究有些遗憾,所以想趁今年寒假--工作前最后一个假期,重新实现一下BabyOS,力求尽量用自己的代码实现。所以前几天学习了一下AT&T 汇编、内联汇编及C与汇编的相互调用。下一个问题就是显示,经过许多考虑,这次准备尝试一下图形界面的系统(因为看上去更有趣些),或许有点舍本求末的嫌疑,但我写个OS kernel主要是好玩,从未想有正式应用,所以怎么好玩就怎么来。
昨晚研究了下BIOS INT 0x10显示字符,今晚决定不管有用没有先学习一下BIOS INT 0x10及实模式下写显存来显示图形的知识。
1.绘制像素
- -----------------------------------------------------------------------
- INT 0x10可识别的视频图形模式
- --------------------------------------------------------------------
- 模式 分辨率(列*行,像素) 颜色数
- 6 640x200 2
- 0DH 320x200 16
- 0EH 640x350 16
- 0FH 640x350 2
- 10H 640x200 16
- 11H 640x480 2
- 12H 640x480 16
- 13H 320x200 256
- 6AH 800x600 16
- -----------------------------------------------------------------------
当视频控制器处于图形模式时,INT 0x10的功能0CH在屏幕上绘制一个像素点。(功能0CH执行的相当慢)
- -----------------------------------------------------------------------
- INT 0x10 功能0CH
- ---------------------------------------------------------------
- 描述:
- 写像素
- 接受参数:
- AH 0CH
- AL 像素值
- BH 视频页
- CX X坐标
- DX Y坐标
- 返回值:
- 无
- 注意:
- 视频显示必须处于图形模式下。像素值的范围和坐标范围与当前的图形模式有关。
- 如果AL的位7置位,新的像素同当前像素的内容进行异或运算。
- -------------------------------------------------------------------------
示例,画线程序:
- # This program draws a straight line in graphics mode.
- # 2012-12-24 20:42
- # guzhoudiaoke@126.com
- .section .text
- .global _start
- .code16
- _start:
- jmp main
- clear_screen: # 清屏函数
- movb $0x06, %ah # 功能号0x06
- movb $0, %al # 上卷全部行,即清屏
- movb $0, %ch # 左上角行
- movb $0, %ch # 左上角列
- movb $24, %dh # 右下角行
- movb $79, %dl # 右下角列
- movb $0x07, %bh # 空白区域属性
- int $0x10
- ret
- main:
- movw %cx, %ax
- movw %ax, %ds
- movw %ax, %es
- call clear_screen # 清屏
- # 设置成图形模式,0x6a为800x600, 16种颜色
- movb $0, %ah # 功能号0x0
- movb $0x6a, %al # 显示模式
- int $0x10
- # 画一条直线
- movb $0x0, %bh # 视频页
- movw $300, %dx # y坐标
- movw $100, %cx # x坐标
- movb $0x0c, %ah # 功能号
- movb $9, %al # 像素值(颜色)
- 1:
- int $0x10
- incw %cx # 下一个像素
- cmpw $700, %cx # 是否到了结束位置
- jne 1b
- 1:
- jmp 1b
- .org 0x1fe, 0x90
- .word 0xaa55
结果:
2.图形模式用功能0x13显示字符串
- # This program draws text and a straight line in graphics mode.
- # 2012-12-24 20:42
- # guzhoudiaoke@126.com
- .section .text
- .global _start
- .code16
- _start:
- jmp main
- clear_screen: # 清屏函数
- movb $0x06, %ah # 功能号0x06
- movb $0, %al # 上卷全部行,即清屏
- movb $0, %ch # 左上角行
- movb $0, %ch # 左上角列
- movb $24, %dh # 右下角行
- movb $79, %dl # 右下角列
- movb $0x07, %bh # 空白区域属性
- int $0x10
- ret
- main:
- movw %cx, %ax
- movw %ax, %ds
- movw %ax, %es
- call clear_screen # 清屏
- # 设置成图形模式,0x6a为800x600, 16种颜色
- movb $0, %ah # 功能号0x0
- movb $0x6a, %al # 显示模式
- int $0x10
- # 显示文字
- movw $msgstr,%ax
- movw %ax, %bp
- movw len, %cx
- movb $0x13, %ah
- movb $0, %al
- movb $0x04, %bl
- movb $0x0, %bh
- movb $0x02, %dh
- movb $0x04, %dl
- int $0x10
- # 画一条直线
- movb $0x0, %bh # 视频页
- movw $300, %dx # y坐标
- movw $100, %cx # x坐标
- movb $0x0c, %ah # 功能号
- movb $9, %al # 像素值(颜色)
- 1:
- int $0x10
- incw %cx # 下一个像素
- cmpw $700, %cx # 是否到了结束位置
- jne 1b
- 1:
- jmp 1b
- msgstr:
- .asciz "line: start(100, 300), end(700, 300)\n"
- len:
- .int . - msgstr
- .org 0x1fe, 0x90
- .word 0xaa55
结果:
3.内存映射图形
对于内存映射图形视频模式0x13最容易使用。这时屏幕像素映射为一个字节数组,每个像素一个字节。
共有320*200个像素,因为有256种颜色,所以每个像素一个字节。左上角像素对应地址0xa0000。
模式0x13中,每个整数色彩值表示调色板的色彩表的索引。调色板中每个项都由三个独立的整数(0~63)构成,称为RGB值。调色板的第0项控制着屏幕的背景色。
有两个输出端口用于控制视频调色板:送往端口0x3c8的值表示要修改的调色板表项,送往端口0x3c9的是要修改的颜色值。
示例:
- # This program draws color pixels at mode 0x13
- # 2012-12-24 21:31
- # guzhoudiaoke@126.com
- .section .text
- .global _start
- .code16
- _start:
- jmp main
- #--------------------------------------------------------------
- # 清屏函数:
- # 设置屏幕背景色,调色板的索引0指代的颜色为背景色
- clear_screen: # 清屏函数
- movb $0x06, %ah # 功能号0x06
- movb $0, %al # 上卷全部行,即清屏
- movb $0, %ch # 左上角行
- movb $0, %ch # 左上角列
- movb $24, %dh # 右下角行
- movb $79, %dl # 右下角列
- movb $0x07, %bh # 空白区域属性
- int $0x10
- ret
- #----------------------------------------------------------------
- # 设置显示模式函数
- set_video_mode:
- movb $0, %ah # 功能号0x0
- movb $MODE_0X13, %al # 显示模式
- int $0x10
- ret
- #---------------------------------------------------------------
- # 显示一些文字函数:
- # 使用INT 0x10中断0x13功能,显示计算机当前工作的显示模式
- draw_some_text:
- movw $msg_str, %bp # ES:BP为字符串地址
- movw msg_len, %cx # 显示字符数
- movb $0x13, %ah # 功能号
- movb $0, %al # 显示模式
- movb $TEXT_COLOR,%bl # 属性值
- movb $0, %bh # 视频页
- movb $TEXT_ROW, %dh # 显示起始行
- movb $TEXT_COL, %dl # 显示起始列
- int $0x10
- ret
- #----------------------------------------------------------------
- # 设置背景颜色为深蓝色
- set_screen_bk_color:
- movw $VIDEO_PALLETE_PORT, %dx
- movb $PA_INDEX_BACKGROUND, %al
- outb %al, %dx
- movw $COLOR_SELECTION_PORT, %dx
- movb $0, %al # 红
- outb %al, %dx
- movb $0, %al # 绿
- outb %al, %dx
- movb $18, %al # 蓝(亮度18/63)
- outb %al, %dx
- ret
- #----------------------------------------------------------------
- # 通过写显存绘制一些像素点:
- # 首先设置调色板索引1处的颜色为白色
- # 然后通过写显存的方式,向ES:DI写入数据(PA_INDEX_WHITE)
- draw_some_pixels:
- # 把索引1处的颜色改为白色(63,63,63)
- movw $VIDEO_PALLETE_PORT, %dx
- movb $PA_INDEX_WHITE, %al
- outb %al, %dx
- movw $COLOR_SELECTION_PORT, %dx
- movb $63, %al # 红
- outb %al, %dx
- movb $63, %al # 绿
- outb %al, %dx
- movb $63, %al # 蓝
- outb %al, %dx
- # 设置ES的值
- movw $VIDEO_SEG_GRAPHIC, %ax
- movw %ax, %es
- # 设置要显示的像素位置的显存地址(目的地址)
- movw $(PIXEL_ROW_ST*320 + PIXEL_COL_ST), %di
- movb $PA_INDEX_WHITE, %al
- movw $PIXEL_COUNT, %cx
- draw_a_pixel:
- stosb
- addw $5, %di
- loop draw_a_pixel
- ret
- main:
- movw %cx, %ax
- movw %ax, %ds
- movw %ax, %es
- call clear_screen # 清屏
- call set_video_mode # 设置显示模式
- call set_screen_bk_color # 设置背景颜色
- call draw_some_text # 绘制字符串
- call draw_some_pixels # 绘制像素
- 1:
- jmp 1b
- # 常量定义:
- VIDEO_SEG_TEXT = 0xb800
- VIDEO_SEG_GRAPHIC = 0xa000
- VIDEO_PALLETE_PORT = 0x3c8
- COLOR_SELECTION_PORT= 0x3c9
- MODE_0X13 = 0x13
- PA_INDEX_BACKGROUND = 0x0
- PA_INDEX_WHITE = 0x1
- TEXT_ROW = 0x01
- TEXT_COL = 0x00
- TEXT_COLOR = 0x04
- PIXEL_ROW_ST = 100
- PIXEL_COL_ST = 160-5*10
- PIXEL_COUNT = 20
- msg_str:
- msg_mode:
- .asciz "video mode: 0x13"
- .org msg_mode+40, 0
- msg_scr_res:
- .asciz "screen resolution:320x200"
- .org msg_scr_res+40, 0
- msg_color_num:
- .asciz "color num:256"
- .org msg_color_num+40*4, 0
- msg_babyos:
- .asciz "The new Baby OS will have a GUI,but now it can only draw some pixels, haha..And merry Christmas!"
- msg_len:
- .int . - msg_str - 1
- .org 0x1fe, 0x90
- .word 0xaa55
结果:
注释:
文字是用的BIOS INT 0x10显示的,VGA的0x13模式下显示的文字为40列x25行,字符框8x8,看上去有点丑,以后再研究下超级VGA(SVGA)吧~
使用BIOS以及直接写显存绘制图形相关推荐
- 绕开BIOS限制修改显存使GVT-g实现更多vGPU
前言废话 为了组一台趁手好使.功耗噪音都能接受的服务器,动手玩了一下KVM,遇到一些百度不到的问题,摸索解决后总结一下,希望能帮到更多人. Intel GVT-g是显卡虚拟化技术,有别于PCI-E设备 ...
- 计算机专业要用多大显卡,10条解答:玩LOL电脑显存一般需要多大啊?
10个答案 1.播放LOL计算机通常需要多少视频内存 宿舍使用512.没关系.显卡为520m.它是独立的.如果网络速度不错,则完全不会卡死.当网络速度不佳时,您将无法行走.最好是图形卡为610或更高. ...
- bios显存改8g rx_【折腾】RX470矿卡刷BIOS变身记
本文是折腾备用机时心血来潮所写,对大部分小白不具备参考意义,仅供自娱自乐. 另外也非常非常非常不推荐小白入手矿卡,除非实在没钱,整机预算2000却想恰鸡.这个时候我认为组一套i3-9100F+H310 ...
- bios设置_bios怎么设置显存 bios设置显存教程【图文】
有些用户可能会发现打开电脑系统信息窗口显示的内存容量与实际容量不同,例如系统内存显示4G,可用3.73G.那么不可用的那部分内存到哪里去了呢?其实是被集成显卡占用当做显存使用了.下面我们就通过 bio ...
- linux gtx1070 黑屏,小编上阵排雷!GTX 1070美光显存门刷BIOS修复教程
早前我们报道过大部分厂商的GTX 1070从三星换用美光GDDR5显存后,由于两者电压参数不一致,导致使用美光显存的GTX 1070显存超频能力远低于预期,甚至有驱动崩溃问题. 现在EVGA官方论坛已 ...
- EFI启动盘修改BIOS隐藏选项DVMT等显存参数提升性能
背景 以前用过联想PC,型号M7360/M4310/M4311/M4320等机型,主板型号均为H61,仅CPU不同.近期拿到较新的M4350机,CPU为三代I3,使用感觉性能并无提升,比之前机型差一点 ...
- 由一位资深测试人员写的docker性能测试引发的思考(缓存、内存、显存、PCIe)
最近想看下docker里运行的服务是否比cpu低,百度看到一篇写docker性能测试的文章,测试的内容很多很细,里面的内容也引起我的思考:硬件对服务器性能的影响. 因为本人对计算机系统了解甚少,所以文 ...
- 显存文本模式详解 ———《x86汇编语言:从实模式到保护模式》读书笔记补遗02
文章修改记录 修改日期 修改内容 2018-2-4 修改了一处错别字:增加了表格的使用方法 今天我们讨论如何编程以在屏幕上显示出彩色的文字. 为了显示文字,通常需要两种硬件--显示器和显卡. 显卡的作 ...
- 提取手机游戏资源 特效 显存分析工具 无视任何加密
step.1 准备工具 1.adb连接工具(我用的cofface adb ) [cofface]adb基于最新安卓源码编译修改,兼容其它助手,增加参数,支持识别所有机型 工具详情:http://blo ...
最新文章
- PHP跳转到另一个画面,并且带着该行内的一个数值作为参数传递给下一个页面.能给例子吗...
- 主流Java数据库连接池比较及前瞻
- C语言 遍历字符串数组
- 干货丨你知道Python中a += b和a = a + b的结果是不一样的吗?
- 通过设置rowcount,从Sybase数据库中分页取数
- OSS音频编程概述(DSP部分)
- 2021年提升效率的7个新vue实战技巧!
- pp助手苹果版本_这可能是最简单的下载APP历史版本方法(支持iOS和安卓)
- Robocode 超级机器人 “波”统计瞄准算法
- [Android] 安卓迅雷带云盘内测版7.0 简洁 无广告 官方版
- GM(1,1)灰色预测模型
- 海量的超赞 Linux 软件
- Apache服务器配置参数的全面说明(所有参数)
- Linux下读取RFID卡号(C串口编程)
- 小程序关注公众号的方法总结
- 移动硬盘 linux找不到,求助!linux对usb设备的接入应该是自动的吧,我的移动硬盘找不到...
- Heap的讲解 - 介绍
- 20170604第四讲
- cdm 图片 转_从CDP到CDM的转变
- TongWeb上应用部署方式
热门文章
- 操作系统原理第十章:文件系统
- 【Android Gradle 插件】ProductFlavor 配置 ( ProductFlavor#buildConfigField 方法 | 单独编译生成 BuildConfig 类的任务 )
- 【Groovy】编译时元编程 ( 利用注解进行 AST 语法树转换 | 定义注解并使用 GroovyASTTransformationClass 注明 AST 转换接口 | AST 转换接口实现 )
- 【EventBus】发布-订阅模式 ( Android 中使用 发布-订阅模式 进行通信 )
- 【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )
- jsp+servlet 导出Excel表格
- ubuntu权限管理
- Lightoj 1123 - Trail Maintenance(最小增量生成树)
- express-14 发送邮件
- 虚拟机上无法运行Gazebo的问题?