前言:

0x03我们提到:

把12(红色)用循环写入显存,每个像素点怎么显示都要看对应的显存地址,比如0xa0000到0xaffff就是每一个像素点的显存

你问为什么12就是红色,这些东西在主板出厂的时候就是规定好的,就是有点调用主板api的味道,这是我的猜测,具体为什么还要你们来查

你会发现12是红色,11就是另一种颜色,有没有办法可以自定义颜色呢

自定义颜色的原因是:

  颜色丰富度不够,因此使用调色板功能来增强颜色显示,使用RGB模式,表示一个RGB颜色需要24位数

修改class01名字为class02,把我给出的代码对原来的内容进行替换,当然你也可以找不同,如果你有这个耐心的话

代码:

naskfunc.asm

; naskfunc
; TAB=4 [FORMAT "WCOFF"] ; 制作目标文件的模式
[INSTRSET "i486p"] ; 使用到486为止的指令
[BITS 32] ; 3制作32位模式用的机器语言
[FILE "naskfunc.asm"] ; 文件名
GLOBAL _io_hlt,_write_mem8,_io_cli,_io_sti,_io_get8,_io_set8,_io_stihlt
GLOBAL _io_load_eflags,_io_store_eflags [SECTION .text] _io_hlt: ; void io_hlt(void);
HLT
RET _io_cli: ; void io_cli(void);
CLI
RET _io_sti: ; void io_sti(void);
STI
RET _io_get8: ; int io_get8(int port);
MOV EDX,[ESP+4] ; port
MOV EAX,0
IN AL,DX
RET _io_set8: ; void io_set8(int port, int data);
MOV EDX,[ESP+4] ; port
MOV AL,[ESP+8] ; data
OUT DX,AL
RET _io_stihlt: ; void io_stihlt(void);
STI
HLT
RET _write_mem8: ; void write_mem8(int addr, int data);
MOV ECX,[ESP+4] ; taking content of add
MOV AL,[ESP+8] ; taking content of data
MOV [ECX],AL ; *ecx=al
RET
_io_load_eflags: ; int io_load_eflags(void);
PUSHFD ; PUSH EFLAGS
POP EAX
RET _io_store_eflags: ; void io_store_eflags(int eflags);
MOV EAX,[ESP+4]
PUSH EAX
POPFD ; POP EFLAGS
RET

这里增加了一些函数,看不懂没关系,我等下调用他们的时候讲一下是干嘛的

新建一个文件graphic.c

#include "include/head.h"

void init_palette(void)
{
static unsigned char table_rgb[18 * 3] = {
0x24, 0x86, 0xb9, /* 0:宝石蓝(#2486b9) */
0xff, 0x00, 0x00, /* 1:梁红 */
0x00, 0xff, 0x00, /* 2:亮绿 */
0xff, 0xff, 0x00, /* 3:亮黄 */
0x00, 0x00, 0xff, /* 4:亮蓝 */
0xff, 0x00, 0xff, /* 5:亮紫 */
0x00, 0xff, 0xff, /* 6:浅亮蓝 */
0xff, 0xff, 0xff, /* 7:白 */
0xc6, 0xc6, 0xc6, /* 8:亮灰 */
0x84, 0x00, 0x00, /* 9:暗红 */
0x00, 0x84, 0x00, /* 10:暗绿 */
0x84, 0x84, 0x00, /* 11:暗黄 */
0x00, 0x00, 0x84, /* 12:暗青 */
0x84, 0x00, 0x84, /* 13:暗紫 */
0x33, 0x33, 0x33, /* 14:浅暗蓝 */
0x84, 0x84, 0x84, /* 15:暗灰 */
0xD0, 0xD0, 0xD0,
0x20, 0x20, 0x20
};
set_palette(0, 17, table_rgb);
return; /* C语言中的static char语句只能用于数据,相当于汇编中的DB指令 */
} void set_palette(int start, int end, unsigned char *rgb)
{
int i, eflags;
eflags = io_load_eflags(); /* 记录中断许可标志的值 */
io_cli(); /* 将中断许可标志置为0,禁止中断 */
io_set8(0x03c8, start);
for (i = start; i <= end; i++) {
io_set8(0x03c9, rgb[0] / 4);
io_set8(0x03c9, rgb[1] / 4);
io_set8(0x03c9, rgb[2] / 4);
rgb += 3;
}
io_store_eflags(eflags); /* 复原中断许可标志 */
return;
}
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{
int x, y;
for (y = y0; y <= y1; y++) {
for (x = x0; x <= x1; x++)
vram[y * xsize + x] = c;
}
return;
}

前两个函数是用来实现调色板的,具体原理我解释不了,Ctrl+CV大佬不需要知道原理,你懂我意思吧,里面调用了很多asm里的函数

第三个函数是绘制方块的参数意思分别是:显存地址,显示宽度,颜色代号,从x0到x1,y0到y1进行绘制一个矩形

head.h

/*naskfunc.asm*/
void io_stihlt();
void io_hlt(void);
void io_cli(void);
void io_sti(void);
int io_get8(int port);
void io_set8(int port, int data);
void write_mem8(int addr, int data);
int io_load_eflags(void);
void io_store_eflags(int eflags); /* asmhead.nas */
struct BOOTINFO { /* 0x0ff0-0x0fff */
char cyls; /* 启动区读磁盘读到此为止 */
char leds; /* 启动时键盘的LED的状态 */
char vmode; /* 显卡模式为多少位彩色 */
char reserve;
short scrnx, scrny; /* 画面分辨率 */
char *vram;
};
#define ADR_BOOTINFO 0x00000ff0 /*graphic.c*/
void init_palette(void);
void set_palette(int start, int end, unsigned char *rgb);
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);

我们主要看第二个asmhead.asm的函数声明,这个BOOTINFO结构体,是涵盖了显示器的信息,信息的位置在0x0ff0-0x0ffff

main.c

#include "include/head.h"

struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;

void Main(void){
int i;
init_palette();
boxfill8(binfo->vram, binfo->scrnx, 0,0,0,binfo->scrnx, binfo->scrny);
for (;;) {
io_hlt();
}
}

第一句是获取这个显示器信息的结构体,调用boxfill8填充整个屏幕,颜色代号是调色板中的0号宝石蓝

最后在make脚本中增加graphic.obj

运行:

cd class02
..\z_tools\make.exe run

自制操作系统合集
原文地址:https://www.cnblogs.com/Frank-dev-blog/category/2249116.html

0x04_My-OS实现自定义颜色的更多相关文章

  1. NodeJs之OS

    OS Node.js提供了一些基本的底层操作系统的模块OS. API var os = require('os'); console.log('[arch] 操作系统CPU架构'+os.arch()) ...

  2. Node.js:OS模块

    os模块,可以用来获取操作系统相关的信息和机器物理信息,例如操作系统平台,内核,cpu架构,内存,cpu,网卡等信息. 使用如下所示: const os = require('os'); var de ...

  3. Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验

    Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...

  4. Mac OS 使用 Vagrant 管理虚拟机(VirtualBox)

    Vagrant(官网.github)是一款构建虚拟开发环境的工具,支持 Window,Linux,Mac OS,Vagrant 中的 Boxes 概念类似于 Docker(实质是不同的),你可以把它看 ...

  5. Mac OS、Ubuntu 安装及使用 Consul

    Consul 概念(摘录): Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,比如 Airbnb 的 SmartStac ...

  6. java 利用ManagementFactory获取jvm,os的一些信息--转

    原文地址:http://blog.csdn.net/dream_broken/article/details/49759043 想了解下某个Java项目的运行时jvm的情况,可以使用一些监控工具,比如 ...

  7. 让 ASP.NET vNext 在 Mac OS 中飞呀飞。。。

    写在前面 阅读目录: 娓娓道来 Install ASP.NET vNext Command Line Tools 安装 Homebrew 使用 Homebrew,安装 KVM Install Subl ...

  8. Mac OS X 上编写 ASP.NET vNext (二) IDE配置

    上一篇中介绍了如何在OS X上搭建.Net运行时.不过光有运行时还不够,还需要有一个好用的IDE,有了IDE的支持,OS X上的开发才称为可能. 和上篇类似,这里先列举出具体步骤,个人可以根据自己的情 ...

  9. 在Mac OS X上安装ASP.NET 5(译文)

    ASP.NET 5 运行在包括OS X的可用于多个平台的.NET Execution Environment(DNX)上.本文介绍如何在OS X上通过HomeBrew安装DNX和ASP.NET 5. ...

  10. Python标准模块--os

    1.模块简介 os模块主要包含普遍的操作系统相关操作,如果开发者希望自己开发的Python应用能够与平台无关,尤其需要关注os这个模块. 2.模块使用 2.1 os模块 1. os.name,输出字符 ...

随机推荐

  1. 1.2 Hadoop简介-hadoop-最全最完整的保姆级的java大数据学习资料

    目录 1.2 Hadoop简介 1.2.1 什么是Hadoop 1.2.2 Hadoop的起源 1.2.3 Hadoop的特点 1.2.4 Hadoop的发行版本 1.2.5 Apache Hadoo ...

  2. 【SQL知识】SQL中的join操作总结:内连接、外连接(左右全)

    一.含义 基于表之间的共同字段,把来自两个或多个表的行结合起来 二.分类 内连接:join / inner join 外连接:left join / right join / full outer j ...

  3. 自己动手基于 Redis 实现一个 .NET 的分布式锁

    分布式锁的核心其实就是采用一个集中式的服务,然后多个应用节点进行抢占式锁定来进行实现,今天介绍如何采用Redis作为基础服务,实现一个分布式锁的类库,本方案不考虑 Redis 集群多节点问题,如果引入 ...

  4. JavaScript冒泡排序+Vue可视化冒泡动画

    冒泡排序(Bubble Sort)算是前端最简单的算法,也是最经典的排序算法了.网上JavaScript版本的冒泡排序很多,今天用Vue实现一个动态的可视化冒泡排序. 01.JavaScript冒泡排 ...

  5. java中的杨辉三角

    本文主要介绍如何打印杨辉三角(直角三角形),如下图所示: 规律如下: 第一行全为1,对角线元素全为1,设i表示行标,j表示列标. arr[i][0] = 1; arr[i][i] = 1; 当i &g ...

  6. js 中常用函数汇总(含示例)

    〇.前言 js 在日常开发中还是比较常用的,本文将常用的 js 方法简单汇总一下,希望对你我有一点帮助. 一.重复 / 延迟操作 1.设置固定时间间隔,重复执行(setInterval(funcRef ...

  7. js 获取当前时间转换时间戳 (毫秒)

    js 当前时间转换毫秒数 五种方式   var date = new Date().getTime(); var date = new Date().valueOf(); var date = +ne ...

  8. JS切换图片

    用js,做图片切换 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  9. Windows上使用QEMU创建银河麒麟ARM64虚拟机完全手册

    "好记性不如烂笔头." -- 张溥 0x00 大纲 目录 0x00 大纲 0x01 前言 0x02 物料准备 0x03 安装 QEMU 0x04 创建虚拟磁盘 0x05 安装麒麟系 ...

  10. Spring学习笔记 - 第三章 - AOP与Spring事务

    原文地址:Spring学习笔记 - 第三章 - AOP与Spring事务 Spring 学习笔记全系列传送门: Spring学习笔记 - 第一章 - IoC(控制反转).IoC容器.Bean的实例化与 ...