提示:可以将virtualbox虚拟机界面大小设置大一些。https://jingyan.baidu.com/article/6525d4b13b7d0fac7d2e94ef.html
1、设置背景色为白色
设置背景色为白色前提条件:
需要要将VGA显卡设置为图形模式,在boot中写,代码如下:
;;;;;;;;;;;;;;;;;;;;;;;;;;;设置VGA图形格式
mov al, 0x13
mov ah, 0x00
int 0x10
;;;;;;;;;;;;;;;;;;;;;;;;;;;
AH=0x00;
AL=模式:(省略了一些不重要的画面模式)
0x03:16位字符模式,80x25
0x12:VGA图形模式,640x480x4位彩色模式,独特的4面存储模式
0x13:VGA图形模式,320x200x8位彩色模式,调色板模式
0x6a:扩展VGA图形模式,800x600x4位彩色模式,独特的4面存储模式(有的显卡不支持这种模式)
返回值:无
我们暂且选择0x13模式,因为8位彩色模式可以使用256种颜色,这一点看来不错。
写显卡
; 导出函数
global write_mem8
[SECTION .text]
; ========================================================================
; void write_mem8(int addr, int data);
; ========================================================================
write_mem8:
mov ecx, [esp + 4] ; [esp + 4]中存放的是地址,将其读入ecx
mov al, [esp + 8] ; [esp + 8]中存放的是数据,将其读入al
mov [ecx], al
ret
c语言设置背景色位白色
void set_background_white(){
for(int i = 0xa0000; i<=0xaffff; i++){
write_mem8(i, 15);
}
}
2、设置背景为条纹图案
条纹背景void set_background_stripe(){
for(int i = 0xa0000; i<=0xaffff; i++){
write_mem8(i, i & 0x0f);
}
}
c语言可以直接使用指针操作内存,不用借助于汇编!
char *p; // 用于BYTE类地址
short *p // 用于WORD类地址
int *p // 用于DWORD类地址
void set_background_stripe(){
char *p;
for(int i = 0xa0000; i<=0xaffff; i++){
p = (char *) i;
*p = i & 0x0f;
}
}
3、设置调色板,色号
这次使用的是320x200的8位颜色模式,色号使用8位(二进制)数,也就是只能使用0~255的数。
RGB使用6位16进制数,也就是24位(二进制)来指定颜色。
这个8位彩色模式,是由程序随意指定0~255的数字所对应的颜色的。
例如25号颜色对应#ffffff,26号颜色对应对应#123456,等,这种方式叫叫做调色板。(palette)
如果程序员不做任何设定,0号颜色就是#000000,15号颜色就是#ffffff。
c:初始化调色板
// 初始化调色板
void init_palette(){
// 我们只设置如下16种颜色就可以了
static unsigned char table_rgb[16*3] = {
0x00, 0x00, 0x00, // 0:黑
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:暗紫
0x00, 0x84, 0x84, // 14:浅暗蓝
0x84, 0x84, 0x84, // 15:暗灰
};
set_palette(0, 15, table_rgb);
}
// 设置调色板
void set_palette(int start, int end, unsigned char *rgb){
int eflags = io_load_eflags(); // 记录中断许可标志的值
io_cli(); // 将中断许可标志置为0,禁止中断
io_out8(0x03c8, start);
for(int i = start; i <= end; i++){
io_out8(0x03c9, rgb[0] / 4);
io_out8(0x03c9, rgb[1] / 4);
io_out8(0x03c9, rgb[2] / 4);
rgb += 3;
}
io_store_eflags(eflags);
}
asm:依赖函数
; ========================================================================
; void io_out8(int port, int data);
; ========================================================================
io_out8:
mov edx, [esp + 4] ; port
mov al, [esp + 8] ; data
mov dx, al
ret
; ========================================================================
; int io_load_eflags();
; ========================================================================
io_load_eflags:
pushfd ; 指push eflags
pop eax ; 函数执行完毕后,如果返回值小于等于4字节,则会将值保存在寄存器eax中
ret
; ========================================================================
; void io_store_eflags(int eflags);
; ========================================================================
io_load_eflags:
mov eax, [esp + 4]
push eax
popfd ; 指pop eflags
ret
; ========================================================================
; void io_cli();
; ========================================================================
io_cli:
cli
ret
c语言函数返回值问题
:https://blog.csdn.net/wanna_wsl/article/details/70550825
4、绘制矩形
画面上由320x200=64000个像素。
假设左上点的坐标是(0, 0),右下点的坐标是(319, 199),那么像素坐标(x,y)对应的VRAM地址为:
0xa0000 + x + y*320
绘制函数
// 绘制矩形
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1){
for(int y = y0; y <= y1; y++){
for(int x = x0; x <= x1; x++){
vram[y * xsize + x] = c;
}
}
}
调用
// 绘制矩形
char *p = (char *) 0xa0000;
boxfill8(p, 320, COL8_FF0000, 20, 20, 120, 120);
boxfill8(p, 320, COL8_00FF00, 70, 50, 170, 150);
boxfill8(p, 320, COL8_0000FF, 120, 80, 220, 180);
5、绘制界面
效果// 绘制ui
void draw_ui(){
init_palette();
char *vram = (char *) 0xa0000;
const int xsize = 320;
const int ysize = 200;
boxfill8(vram, xsize, COL8_008484, 0, 0, xsize - 1, ysize - 29);
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-28, xsize - 1, ysize - 28);
boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize-27, xsize - 1, ysize - 27);
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-26, xsize - 1, ysize - 1);
boxfill8(vram, xsize, COL8_FFFFFF, 3, ysize-24, 59, ysize -24);
boxfill8(vram, xsize, COL8_FFFFFF, 2, ysize-24, 2, ysize - 4);
boxfill8(vram, xsize, COL8_848484, 3, ysize- 4, 59, ysize - 4);
boxfill8(vram, xsize, COL8_848484, 59, ysize-23, 59, ysize - 5);
boxfill8(vram, xsize, COL8_000000, 2, ysize- 3, 59, ysize - 3);
boxfill8(vram, xsize, COL8_000000, 60, ysize-24, 60, ysize - 3);
boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize- 24, xsize - 4, ysize - 24);
boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize- 23, xsize -47, ysize - 4);
boxfill8(vram, xsize, COL8_FFFFFF, xsize - 47, ysize- 3, xsize - 4, ysize - 3);
boxfill8(vram, xsize, COL8_FFFFFF, xsize - 3, ysize- 24, xsize - 3, ysize - 3);
}
网友评论