注:以下程序系由相应的Intel格式汇编改编而来,略有修改,若发现bug,欢迎指正。若有问题,欢迎交流。若能帮助一二访客,幸甚。

一年前仿照Skelix 写过一个简单的内核,并命名为BabyOS。当时代码大部分用的Skelix的,终究有些遗憾,所以想趁今年寒假--工作前最后一个假期,重新实现一下BabyOS,力求尽量用自己的代码实现。所以前几天学习了一下AT&T 汇编、内联汇编及C与汇编的相互调用。下一个问题就是显示,经过许多考虑,这次准备尝试一下图形界面的系统(因为看上去更有趣些),或许有点舍本求末的嫌疑,但我写个OS kernel主要是好玩,从未想有正式应用,所以怎么好玩就怎么来。

昨晚研究了下BIOS INT 0x10显示字符,今晚决定不管有用没有先学习一下BIOS INT 0x10及实模式下写显存来显示图形的知识。

1.绘制像素

[cpp] view plaincopyprint?
  1. -----------------------------------------------------------------------
  2. INT 0x10可识别的视频图形模式
  3. --------------------------------------------------------------------
  4. 模式          分辨率(列*行,像素)   颜色数
  5. 6                   640x200                 2
  6. 0DH                 320x200                 16
  7. 0EH                 640x350                 16
  8. 0FH                 640x350                 2
  9. 10H                 640x200                 16
  10. 11H                 640x480                 2
  11. 12H                 640x480                 16
  12. 13H                 320x200                 256
  13. 6AH                 800x600                 16
  14. -----------------------------------------------------------------------

当视频控制器处于图形模式时,INT 0x10的功能0CH在屏幕上绘制一个像素点。(功能0CH执行的相当慢)

[cpp] view plaincopyprint?
  1. -----------------------------------------------------------------------
  2. INT 0x10 功能0CH
  3. ---------------------------------------------------------------
  4. 描述:
  5. 写像素
  6. 接受参数:
  7. AH          0CH
  8. AL          像素值
  9. BH          视频页
  10. CX          X坐标
  11. DX          Y坐标
  12. 返回值:
  13. 注意:
  14. 视频显示必须处于图形模式下。像素值的范围和坐标范围与当前的图形模式有关。
  15. 如果AL的位7置位,新的像素同当前像素的内容进行异或运算。
  16. -------------------------------------------------------------------------

示例,画线程序:

[cpp] view plaincopyprint?
  1. # This program draws a straight line in graphics mode.
  2. # 2012-12-24 20:42
  3. # guzhoudiaoke@126.com
  4. .section .text
  5. .global _start
  6. .code16
  7. _start:
  8. jmp     main
  9. clear_screen:               # 清屏函数
  10. movb    $0x06,  %ah     # 功能号0x06
  11. movb    $0,     %al     # 上卷全部行,即清屏
  12. movb    $0,     %ch     # 左上角行
  13. movb    $0,     %ch     # 左上角列
  14. movb    $24,    %dh     # 右下角行
  15. movb    $79,    %dl     # 右下角列
  16. movb    $0x07,  %bh     # 空白区域属性
  17. int     $0x10
  18. ret
  19. main:
  20. movw    %cx,    %ax
  21. movw    %ax,    %ds
  22. movw    %ax,    %es
  23. call    clear_screen    # 清屏
  24. # 设置成图形模式,0x6a为800x600, 16种颜色
  25. movb    $0,     %ah     # 功能号0x0
  26. movb    $0x6a,  %al     # 显示模式
  27. int     $0x10
  28. # 画一条直线
  29. movb    $0x0,   %bh     # 视频页
  30. movw    $300,   %dx     # y坐标
  31. movw    $100,   %cx     # x坐标
  32. movb    $0x0c,  %ah     # 功能号
  33. movb    $9,     %al     # 像素值(颜色)
  34. 1:
  35. int     $0x10
  36. incw    %cx             # 下一个像素
  37. cmpw    $700,   %cx     # 是否到了结束位置
  38. jne     1b
  39. 1:
  40. jmp     1b
  41. .org    0x1fe,  0x90
  42. .word   0xaa55

结果:

2.图形模式用功能0x13显示字符串

[cpp] view plaincopyprint?
  1. # This program draws text and a straight line in graphics mode.
  2. # 2012-12-24 20:42
  3. # guzhoudiaoke@126.com
  4. .section .text
  5. .global _start
  6. .code16
  7. _start:
  8. jmp     main
  9. clear_screen:               # 清屏函数
  10. movb    $0x06,  %ah     # 功能号0x06
  11. movb    $0,     %al     # 上卷全部行,即清屏
  12. movb    $0,     %ch     # 左上角行
  13. movb    $0,     %ch     # 左上角列
  14. movb    $24,    %dh     # 右下角行
  15. movb    $79,    %dl     # 右下角列
  16. movb    $0x07,  %bh     # 空白区域属性
  17. int     $0x10
  18. ret
  19. main:
  20. movw    %cx,    %ax
  21. movw    %ax,    %ds
  22. movw    %ax,    %es
  23. call    clear_screen    # 清屏
  24. # 设置成图形模式,0x6a为800x600, 16种颜色
  25. movb    $0,     %ah     # 功能号0x0
  26. movb    $0x6a,  %al     # 显示模式
  27. int     $0x10
  28. # 显示文字
  29. movw    $msgstr,%ax
  30. movw    %ax,    %bp
  31. movw    len,    %cx
  32. movb    $0x13,  %ah
  33. movb    $0,     %al
  34. movb    $0x04,  %bl
  35. movb    $0x0,   %bh
  36. movb    $0x02,  %dh
  37. movb    $0x04,  %dl
  38. int     $0x10
  39. # 画一条直线
  40. movb    $0x0,   %bh     # 视频页
  41. movw    $300,   %dx     # y坐标
  42. movw    $100,   %cx     # x坐标
  43. movb    $0x0c,  %ah     # 功能号
  44. movb    $9,     %al     # 像素值(颜色)
  45. 1:
  46. int     $0x10
  47. incw    %cx             # 下一个像素
  48. cmpw    $700,   %cx     # 是否到了结束位置
  49. jne     1b
  50. 1:
  51. jmp     1b
  52. msgstr:
  53. .asciz  "line: start(100, 300), end(700, 300)\n"
  54. len:
  55. .int    . - msgstr
  56. .org    0x1fe,  0x90
  57. .word   0xaa55

结果:

3.内存映射图形

对于内存映射图形视频模式0x13最容易使用。这时屏幕像素映射为一个字节数组,每个像素一个字节。
共有320*200个像素,因为有256种颜色,所以每个像素一个字节。左上角像素对应地址0xa0000。
模式0x13中,每个整数色彩值表示调色板的色彩表的索引。调色板中每个项都由三个独立的整数(0~63)构成,称为RGB值。调色板的第0项控制着屏幕的背景色。
有两个输出端口用于控制视频调色板:送往端口0x3c8的值表示要修改的调色板表项,送往端口0x3c9的是要修改的颜色值。
示例:

[cpp] view plaincopyprint?
  1. # This program draws color pixels at mode 0x13
  2. # 2012-12-24 21:31
  3. # guzhoudiaoke@126.com
  4. .section .text
  5. .global _start
  6. .code16
  7. _start:
  8. jmp     main
  9. #--------------------------------------------------------------
  10. # 清屏函数:
  11. #   设置屏幕背景色,调色板的索引0指代的颜色为背景色
  12. clear_screen:               # 清屏函数
  13. movb    $0x06,  %ah     # 功能号0x06
  14. movb    $0,     %al     # 上卷全部行,即清屏
  15. movb    $0,     %ch     # 左上角行
  16. movb    $0,     %ch     # 左上角列
  17. movb    $24,    %dh     # 右下角行
  18. movb    $79,    %dl     # 右下角列
  19. movb    $0x07,  %bh     # 空白区域属性
  20. int     $0x10
  21. ret
  22. #----------------------------------------------------------------
  23. # 设置显示模式函数
  24. set_video_mode:
  25. movb    $0,         %ah         # 功能号0x0
  26. movb    $MODE_0X13, %al         # 显示模式
  27. int     $0x10
  28. ret
  29. #---------------------------------------------------------------
  30. # 显示一些文字函数:
  31. #   使用INT 0x10中断0x13功能,显示计算机当前工作的显示模式
  32. draw_some_text:
  33. movw    $msg_str,   %bp         # ES:BP为字符串地址
  34. movw    msg_len,    %cx         # 显示字符数
  35. movb    $0x13,      %ah         # 功能号
  36. movb    $0,         %al         # 显示模式
  37. movb    $TEXT_COLOR,%bl         # 属性值
  38. movb    $0,         %bh         # 视频页
  39. movb    $TEXT_ROW,  %dh         # 显示起始行
  40. movb    $TEXT_COL,  %dl         # 显示起始列
  41. int     $0x10
  42. ret
  43. #----------------------------------------------------------------
  44. # 设置背景颜色为深蓝色
  45. set_screen_bk_color:
  46. movw    $VIDEO_PALLETE_PORT,    %dx
  47. movb    $PA_INDEX_BACKGROUND,   %al
  48. outb    %al,                    %dx
  49. movw    $COLOR_SELECTION_PORT,  %dx
  50. movb    $0,                     %al     # 红
  51. outb    %al,                    %dx
  52. movb    $0,                     %al     # 绿
  53. outb    %al,                    %dx
  54. movb    $18,                    %al     # 蓝(亮度18/63)
  55. outb    %al,                    %dx
  56. ret
  57. #----------------------------------------------------------------
  58. # 通过写显存绘制一些像素点:
  59. #   首先设置调色板索引1处的颜色为白色
  60. #   然后通过写显存的方式,向ES:DI写入数据(PA_INDEX_WHITE)
  61. draw_some_pixels:
  62. # 把索引1处的颜色改为白色(63,63,63)
  63. movw    $VIDEO_PALLETE_PORT,    %dx
  64. movb    $PA_INDEX_WHITE,        %al
  65. outb    %al,                    %dx
  66. movw    $COLOR_SELECTION_PORT,  %dx
  67. movb    $63,                    %al     # 红
  68. outb    %al,                    %dx
  69. movb    $63,                    %al     # 绿
  70. outb    %al,                    %dx
  71. movb    $63,                    %al     # 蓝
  72. outb    %al,                    %dx
  73. # 设置ES的值
  74. movw    $VIDEO_SEG_GRAPHIC,     %ax
  75. movw    %ax,                    %es
  76. # 设置要显示的像素位置的显存地址(目的地址)
  77. movw    $(PIXEL_ROW_ST*320 + PIXEL_COL_ST), %di
  78. movb    $PA_INDEX_WHITE,        %al
  79. movw    $PIXEL_COUNT,           %cx
  80. draw_a_pixel:
  81. stosb
  82. addw    $5,                     %di
  83. loop    draw_a_pixel
  84. ret
  85. main:
  86. movw    %cx,    %ax
  87. movw    %ax,    %ds
  88. movw    %ax,    %es
  89. call    clear_screen        # 清屏
  90. call    set_video_mode      # 设置显示模式
  91. call    set_screen_bk_color # 设置背景颜色
  92. call    draw_some_text      # 绘制字符串
  93. call    draw_some_pixels    # 绘制像素
  94. 1:
  95. jmp     1b
  96. # 常量定义:
  97. VIDEO_SEG_TEXT      = 0xb800
  98. VIDEO_SEG_GRAPHIC   = 0xa000
  99. VIDEO_PALLETE_PORT  = 0x3c8
  100. COLOR_SELECTION_PORT= 0x3c9
  101. MODE_0X13           = 0x13
  102. PA_INDEX_BACKGROUND = 0x0
  103. PA_INDEX_WHITE      = 0x1
  104. TEXT_ROW            = 0x01
  105. TEXT_COL            = 0x00
  106. TEXT_COLOR          = 0x04
  107. PIXEL_ROW_ST        = 100
  108. PIXEL_COL_ST        = 160-5*10
  109. PIXEL_COUNT         = 20
  110. msg_str:
  111. msg_mode:
  112. .asciz  "video mode: 0x13"
  113. .org    msg_mode+40,        0
  114. msg_scr_res:
  115. .asciz  "screen resolution:320x200"
  116. .org    msg_scr_res+40,     0
  117. msg_color_num:
  118. .asciz  "color num:256"
  119. .org    msg_color_num+40*4, 0
  120. msg_babyos:
  121. .asciz  "The new Baby OS will have a GUI,but now it can only draw some pixels, haha..And merry Christmas!"
  122. msg_len:
  123. .int    . - msg_str - 1
  124. .org    0x1fe,  0x90
  125. .word   0xaa55

结果:

注释:

文字是用的BIOS INT 0x10显示的,VGA的0x13模式下显示的文字为40列x25行,字符框8x8,看上去有点丑,以后再研究下超级VGA(SVGA)吧~

使用BIOS以及直接写显存绘制图形相关推荐

  1. 绕开BIOS限制修改显存使GVT-g实现更多vGPU

    前言废话 为了组一台趁手好使.功耗噪音都能接受的服务器,动手玩了一下KVM,遇到一些百度不到的问题,摸索解决后总结一下,希望能帮到更多人. Intel GVT-g是显卡虚拟化技术,有别于PCI-E设备 ...

  2. 计算机专业要用多大显卡,10条解答:玩LOL电脑显存一般需要多大啊?

    10个答案 1.播放LOL计算机通常需要多少视频内存 宿舍使用512.没关系.显卡为520m.它是独立的.如果网络速度不错,则完全不会卡死.当网络速度不佳时,您将无法行走.最好是图形卡为610或更高. ...

  3. bios显存改8g rx_【折腾】RX470矿卡刷BIOS变身记

    本文是折腾备用机时心血来潮所写,对大部分小白不具备参考意义,仅供自娱自乐. 另外也非常非常非常不推荐小白入手矿卡,除非实在没钱,整机预算2000却想恰鸡.这个时候我认为组一套i3-9100F+H310 ...

  4. bios设置_bios怎么设置显存 bios设置显存教程【图文】

    有些用户可能会发现打开电脑系统信息窗口显示的内存容量与实际容量不同,例如系统内存显示4G,可用3.73G.那么不可用的那部分内存到哪里去了呢?其实是被集成显卡占用当做显存使用了.下面我们就通过 bio ...

  5. linux gtx1070 黑屏,小编上阵排雷!GTX 1070美光显存门刷BIOS修复教程

    早前我们报道过大部分厂商的GTX 1070从三星换用美光GDDR5显存后,由于两者电压参数不一致,导致使用美光显存的GTX 1070显存超频能力远低于预期,甚至有驱动崩溃问题. 现在EVGA官方论坛已 ...

  6. EFI启动盘修改BIOS隐藏选项DVMT等显存参数提升性能

    背景 以前用过联想PC,型号M7360/M4310/M4311/M4320等机型,主板型号均为H61,仅CPU不同.近期拿到较新的M4350机,CPU为三代I3,使用感觉性能并无提升,比之前机型差一点 ...

  7. 由一位资深测试人员写的docker性能测试引发的思考(缓存、内存、显存、PCIe)

    最近想看下docker里运行的服务是否比cpu低,百度看到一篇写docker性能测试的文章,测试的内容很多很细,里面的内容也引起我的思考:硬件对服务器性能的影响. 因为本人对计算机系统了解甚少,所以文 ...

  8. 显存文本模式详解 ———《x86汇编语言:从实模式到保护模式》读书笔记补遗02

    文章修改记录 修改日期 修改内容 2018-2-4 修改了一处错别字:增加了表格的使用方法 今天我们讨论如何编程以在屏幕上显示出彩色的文字. 为了显示文字,通常需要两种硬件--显示器和显卡. 显卡的作 ...

  9. 提取手机游戏资源 特效 显存分析工具 无视任何加密

    step.1 准备工具 1.adb连接工具(我用的cofface adb ) [cofface]adb基于最新安卓源码编译修改,兼容其它助手,增加参数,支持识别所有机型 工具详情:http://blo ...

最新文章

  1. PHP跳转到另一个画面,并且带着该行内的一个数值作为参数传递给下一个页面.能给例子吗...
  2. 主流Java数据库连接池比较及前瞻
  3. C语言 遍历字符串数组
  4. 干货丨你知道Python中a += b和a = a + b的结果是不一样的吗?
  5. 通过设置rowcount,从Sybase数据库中分页取数
  6. OSS音频编程概述(DSP部分)
  7. 2021年提升效率的7个新vue实战技巧!
  8. pp助手苹果版本_这可能是最简单的下载APP历史版本方法(支持iOS和安卓)
  9. Robocode 超级机器人 “波”统计瞄准算法
  10. [Android] 安卓迅雷带云盘内测版7.0 简洁 无广告 官方版
  11. GM(1,1)灰色预测模型
  12. 海量的超赞 Linux 软件
  13. Apache服务器配置参数的全面说明(所有参数)
  14. Linux下读取RFID卡号(C串口编程)
  15. 小程序关注公众号的方法总结
  16. 移动硬盘 linux找不到,求助!linux对usb设备的接入应该是自动的吧,我的移动硬盘找不到...
  17. Heap的讲解 - 介绍
  18. 20170604第四讲
  19. cdm 图片 转_从CDP到CDM的转变
  20. TongWeb上应用部署方式

热门文章

  1. 操作系统原理第十章:文件系统
  2. 【Android Gradle 插件】ProductFlavor 配置 ( ProductFlavor#buildConfigField 方法 | 单独编译生成 BuildConfig 类的任务 )
  3. 【Groovy】编译时元编程 ( 利用注解进行 AST 语法树转换 | 定义注解并使用 GroovyASTTransformationClass 注明 AST 转换接口 | AST 转换接口实现 )
  4. 【EventBus】发布-订阅模式 ( Android 中使用 发布-订阅模式 进行通信 )
  5. 【约束布局】ConstraintLayout 13 种相对定位属性组合 ( 属性组合 | 用法说明 )
  6. jsp+servlet 导出Excel表格
  7. ubuntu权限管理
  8. Lightoj 1123 - Trail Maintenance(最小增量生成树)
  9. express-14 发送邮件
  10. 虚拟机上无法运行Gazebo的问题?