0x04_My-OS实现自定义颜色
前言:
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

0x04_My-OS实现自定义颜色的更多相关文章
- NodeJs之OS
OS Node.js提供了一些基本的底层操作系统的模块OS. API var os = require('os'); console.log('[arch] 操作系统CPU架构'+os.arch()) ...
- Node.js:OS模块
os模块,可以用来获取操作系统相关的信息和机器物理信息,例如操作系统平台,内核,cpu架构,内存,cpu,网卡等信息. 使用如下所示: const os = require('os'); var de ...
- Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验
Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...
- Mac OS 使用 Vagrant 管理虚拟机(VirtualBox)
Vagrant(官网.github)是一款构建虚拟开发环境的工具,支持 Window,Linux,Mac OS,Vagrant 中的 Boxes 概念类似于 Docker(实质是不同的),你可以把它看 ...
- Mac OS、Ubuntu 安装及使用 Consul
Consul 概念(摘录): Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,比如 Airbnb 的 SmartStac ...
- java 利用ManagementFactory获取jvm,os的一些信息--转
原文地址:http://blog.csdn.net/dream_broken/article/details/49759043 想了解下某个Java项目的运行时jvm的情况,可以使用一些监控工具,比如 ...
- 让 ASP.NET vNext 在 Mac OS 中飞呀飞。。。
写在前面 阅读目录: 娓娓道来 Install ASP.NET vNext Command Line Tools 安装 Homebrew 使用 Homebrew,安装 KVM Install Subl ...
- Mac OS X 上编写 ASP.NET vNext (二) IDE配置
上一篇中介绍了如何在OS X上搭建.Net运行时.不过光有运行时还不够,还需要有一个好用的IDE,有了IDE的支持,OS X上的开发才称为可能. 和上篇类似,这里先列举出具体步骤,个人可以根据自己的情 ...
- 在Mac OS X上安装ASP.NET 5(译文)
ASP.NET 5 运行在包括OS X的可用于多个平台的.NET Execution Environment(DNX)上.本文介绍如何在OS X上通过HomeBrew安装DNX和ASP.NET 5. ...
- Python标准模块--os
1.模块简介 os模块主要包含普遍的操作系统相关操作,如果开发者希望自己开发的Python应用能够与平台无关,尤其需要关注os这个模块. 2.模块使用 2.1 os模块 1. os.name,输出字符 ...
随机推荐
- 模块/collections/random/time/datetime
内容概要 模块--包的具体使用 编程思想介绍 软件开发--目录规范 常用模块介绍--collections模块 常用模块介绍--time.datetime 常用模块介绍--random 1.包的具体使 ...
- python 爬取豆瓣电影评论,并进行词云展示
python 爬取豆瓣电影评论,并进行词云展示 本文旨在提供爬取豆瓣电影<我不是药神>评论和词云展示的代码样例 1.分析URL 2.爬取前10页评论 3.进行词云展示 1.分析URL 我不 ...
- mouseMove模拟拖拽,封装指令
最近项目里常常使用拖拽改变元素位置或者大小的需求,cv法文件找的脑阔疼,索性试试写一个指令. 说起指令,提一嘴,vue3没有了根元素唯一的限制后,仿佛指令绑定在组件上就不能生效了. import ty ...
- CBV如何添加装饰器?
目录 一:CBV如何添加装饰器 1.CBV中django不建议直接给类的方法加装饰器 2.CBC添加装饰器的三种方法 3.CBV添加装饰器实战 一:CBV如何添加装饰器 1.CBV中django不建议 ...
- 【机器学习】李宏毅——生成式对抗网络GAN
1.基本概念介绍 1.1.What is Generator 在之前我们的网络架构中,都是对于输入x得到输出y,只要输入x是一样的,那么得到的输出y就是一样的. 但是Generator不一样,它最大的 ...
- .Net执行SQL/存储过程之易用轻量工具
支持.Net/.Net Core/.Net Framework,可以部署在Docker, Windows, Linux, Mac. 由于该工具近来被广东省数个公司2B项目采用,且表现稳定,得到良好验证 ...
- python 实现DES加解密
from pyDes import * import base64 class Des3(object): def __init__(self, key, iv): # 这里密钥key长度必须为16/ ...
- JavaScript:代码应该编写在哪里?
我们可以将JS的代码,编写在三个地方. 但是无论编写在哪里,最后它都会嵌入进网页代码中,被浏览器执行. 编写在script标签中 我们可以直接在HTML的script标签中,编写大段JS代码. 编写在 ...
- 温故知新 - 靶机练习-Toppo
今天闲来无事,重新做了一下以前做过的第一个靶机(https://www.cnblogs.com/sallyzhang/p/12792042.html),这个靶机主要是练习sudo提权,当时不会也没理解 ...
- python 之路 37 Navicat 可视化软件使用、 pymysql模块使用
多表查询的两种方法 方式1:连表操作 inner join 内连接 select * from emp inner join dep on emp.dep_id=dep.id; 只连接两张表中公有的数 ...